package com.zygh.lz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.zygh.lz.dao.*;
import com.zygh.lz.entity.*;
import com.zygh.lz.entity.duty.DutyModel;
import com.zygh.lz.entity.duty.DutyPost;
import com.zygh.lz.entity.duty.DutySchedule;
import com.zygh.lz.entity.remould.OnLine;
import com.zygh.lz.entity.remould.Xareas;
import com.zygh.lz.entity.signfile.SignGeneral;
import com.zygh.lz.entity.signfile.SignGenerals;
import com.zygh.lz.entity.signfile.SignStatistics;
import com.zygh.lz.entity.vo.SignInfoVO;
import com.zygh.lz.service.SignEquipageService;
import com.zygh.lz.service.SignService;
import com.zygh.lz.stapprove.ResultUtil;
import com.zygh.lz.util.*;
import com.zygh.lz.util.SignUtil;
import com.zygh.lz.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.text.*;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.zygh.lz.util.DataTime.isEffectiveDate;
import static com.zygh.lz.util.SignTime.*;

@Slf4j
@Service
public class SignServiceImpl implements SignService {
    @Resource
    private DutyModelMapper dutyModelMapper;
    @Resource
    private SignMapper signMapper;
    @Resource
    private XareaMapper xareaMapper;
    @Resource
    private StaffMapper staffMapper;
    @Resource
    private GpsMapper gpsMapper;
    @Resource
    private XlevelserviceMapper xlevelserviceMapper;
    @Resource
    private ClassesMapper classesMapper;
    @Resource
    private StationMapper stationMapper;
    @Resource
    private SectionMapper sectionMapper;
    @Resource
    private PatrolrecordMapper patrolrecordMapper;
    @Resource
    private GatecardMapper gatecardMapper;
    @Resource
    private IllegalDataMapper illegalDataMapper;
    @Resource
    private PoliceDataMapper policeDataMapper;
    @Resource
    private SignStatisticsMapper signStatisticsMapper;
    @Resource
    private GisLocationMapper gisLocationMapper;
    @Resource
    private SignGeneralMapper signGeneralMapper;
    @Resource
    private EquipageMapper equipageMapper;
    @Resource
    private ProblemMapper problemMapper;
    @Resource
    private LocationMapper locationMapper;
    @Resource
    private SignUtil signUtil;
    @Resource
    private DutyScheduleMapper dutyScheduleMapper;
    @Resource
    private JwtUtils jwtUtils;
    @Resource
    private LongFengService longFengService;

    @Value("${max-depth}")
    private Integer maxDepth;

    @Resource
    SignEquipageService signEquipageService;

    //设置日期格式
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");


    /**
     * 签到接口
     * 签到范围提前半个小时
     * <p>
     * 07:30-08:30 早高峰
     * 08:30-18:00 平峰（夏季）        08:30-17:30平峰 非夏季
     * 18:00-19:00 晚高峰(夏季)        17:30-18:30晚高峰
     * 19:00-20:00 平峰(夏季)         18:30-20:00平峰
     * 20:00-次日7:30 夜巡
     *
     * @param sign 签到参数
     * @return ResultBean
     */
    @Override
    public ResultBeans signqd(Sign sign) {
        //判断是否签到。无论日常还是特殊只能签到一个岗位
        Integer integer = signMapper.selectCount(Wrappers.<Sign>lambdaQuery()
                .eq(Sign::getState, 1)
                .eq(Sign::getWarningsignal, sign.getWarningsignal()));
        if (integer > 0) {
            return ResultUtil.resultBeansError("您已签到 ！", null);
        }


        //判断签到获取GPS坐标不能为空
        if (StringUtils.isEmpty(sign.getGpsx()) || StringUtils.isEmpty(sign.getGpsy())) {
            return ResultUtil.resultBeansError("获取不到GPS坐标点！", null);
        }

        if ("1".equals(sign.getComment())) {
            //辖区范围限制
            Section sectionByid = sectionMapper.selectById(Integer.valueOf(sign.getSectionid()));
            Gislocation gislocation = gisLocationMapper.selectOne(Wrappers.<Gislocation>lambdaQuery()
                    .eq(Gislocation::getSysSectionId, sectionByid.getSectionPid()));
            if (gislocation != null && StringUtils.isNotEmpty(gislocation.getBoundary())) {
                String area = gislocation.getBoundary();
                net.sf.json.JSONObject results = net.sf.json.JSONObject.fromObject(area);
                net.sf.json.JSONObject jsons = net.sf.json.JSONObject.fromObject(results.get("geometry"));
                String coordinates = jsons.getString("coordinates");
                String replace = coordinates.replace("[", "");
                String replace1 = replace.replace("]", "");
                Map<String, double[]> border = DistanceUtil.getBorder(replace1);

                boolean result = PatrolrecordServiceImpl.isInPolygon(Double.parseDouble(sign.getGpsx()), Double.parseDouble(sign.getGpsy()), border.get("gpsx"), border.get("gpsy"));
                if (!result) {
                    return ResultUtil.resultBeansError("请在本支队辖区内签到！", null);
                }
            }
        }


        Equipage equipage = new Equipage();
        equipage.setWarningSignal(sign.getWarningsignal());
        equipage.setLongitude(sign.getGpsx());
        equipage.setLatitude(sign.getGpsy());
        equipage.setUploadTime(DateUtil.now());
        equipageMapper.update(equipage, Wrappers.<Equipage>lambdaQuery()
                .eq(Equipage::getWarningSignal, sign.getWarningsignal())
                .like(Equipage::getType, "通"));

        //sign.setShiftop(shiftModelImpl(sign.getSectionname()));
        if ("1".equals(sign.getComment())) {
            Xarea xarea = xareaMapper.selectByPrimaryKey(sign.getAssignmentid());
            //签到模式code
            sign.setModeCode(xarea.getPattern());
            Integer shiftop = signUtil.getShiftop(sign.getModeCode());
            sign.setShiftop(String.valueOf(shiftop));
            //固定岗电子围栏范围判定,区域坐标不能为空；为空默认为其他岗，不做范围判定
            String areaLimits = xarea.getAreaLimit();
            if (StrUtil.isNotEmpty(areaLimits)) {
                Map<String, double[]> border = DistanceUtil.getBorder(areaLimits);

                boolean result = PatrolrecordServiceImpl.isInPolygon(Double.parseDouble(sign.getGpsx()), Double.parseDouble(sign.getGpsy()), border.get("gpsx"), border.get("gpsy"));
                if (!result) {
                    return ResultUtil.resultBeansError("请在本支队围栏限制内签到！", null);
                }
            }
            //不在签到时间范围提前退出
            if (!signUtil.signIn(sign.getModeCode())) {
                return ResultUtil.resultBeansError("您不在该岗位签到时间范围内 ！", null);
            }
            if (("固定岗").equals(xarea.getStation()) && StringUtils.isNotEmpty(xarea.getGps())) {
                String[] split = xarea.getGps().split(",");
                double lat = Double.valueOf(sign.getGpsx());
                double lng = Double.valueOf(sign.getGpsy());
                double circleX = Double.valueOf(split[0]);
                double circley = Double.valueOf(split[1]);
                double raduis = 1000;
                if (DistanceUtil.distencePC(lat, lng, circleX, circley, raduis)) {
                    return scopeDecisions(sign);
                } else {
                    return ResultUtil.resultBeansError("您不在签到范围内 ！", null);
                }

            } else {
                return scopeDecisions(sign);
            }
            /*else if (("夜巡").equals(xarea.getStation())) {
                sign.setShiftop(shiftModelImpl("高架"));
                return scopeDecisions(sign);
            } */
        }
        return scopeDecisions(sign);
    }

    /**
     * 判断签到岗位的班次
     * 高速的是全天班，高架只上夜班
     * 上午班：7：30-13：00
     * 下午班：13：00-20：00
     * 全天班 高速
     * 夜班：20：00-次日7:30 高架
     * 1 代表上午班    2 代表下午班    3 代表夜班    4 代表全天班
     *
     * @param sectionname 大队
     * @return String
     */
    public String shiftModelImpl(String sectionname) {
        LocalTime now = LocalTime.now();
        String time = now.getHour() + ":" + now.getMinute() + ":" + now.getSecond();

        if (sectionname.contains("高速")) {
            return "4";
        } else if (sectionname.contains("高架")) {
            return "3";
        } else {
            if (DateUtil.parse(DateUtil.now()).after(SignTime.getStartDate(MORNINGSESSION)) && DateUtil.parse(DateUtil.now()).before(SignTime.getEndDate(MORNINGSESSION))) {
                return "1";
            }
            if (DateUtil.parse(DateUtil.now()).after(SignTime.getStartDate(AFTERNOONSESSION)) && DateUtil.parse(DateUtil.now()).before(SignTime.getEndDate(AFTERNOONSESSION))) {
                return "2";
            }
            if (new Date().after(SignTime.getStartDate(NIGHTGO)) || new Date().before(SignTime.getEndDate(NIGHTGO))) {
                return "3";
            }
        }
        return time;
    }

    /**
     * 签退接口
     *
     * @param sign 签到参数
     * @return ResultBean
     */
    @Override
    public ResultBeans sifnqt(Sign sign) {
        if (StringUtils.isEmpty(sign.getGpsqtx()) || StringUtils.isEmpty(sign.getGpsqty())) {
            return ResultUtil.resultBeansError("获取不到GPS坐标点!");
        }
        //获取需签退的那条信息
        Sign signInfoByQt = signMapper.findSignInfoByQt(sign);
        if (signInfoByQt == null) {
            return ResultUtil.resultBeansError("您还尚未签到！");
        }
        sign.setId(signInfoByQt.getId());
        sign.setSignouttime(DateUtil.now());
        sign.setState(2);
        signMapper.updateByPrimaryKeySelective(sign);

        //签退结束巡查
        Patrolrecord patrolRecordOne = patrolrecordMapper.findPatrolRecordOne(signInfoByQt.getSignnum());
        if (patrolRecordOne != null) {
            Patrolrecord patrolrecord = new Patrolrecord();
            patrolrecord.setSysPatrolRecordId(patrolRecordOne.getSysPatrolRecordId());
            patrolrecord.setPatrolRecordEndtime(new Date());
            patrolrecordMapper.updateByPrimaryKeySelective(patrolrecord);
        }

        return ResultUtil.resultBeansSuccess("签退成功");

    }


    @Override
    public List<HashMap> findOnlineUser(String battalion) {
        List<HashMap> onlineUser = signMapper.findOnlineUser(battalion);
        if (onlineUser.size() > 0) {
            for (int i = 0; i < onlineUser.size(); i++) {
                String assignmentname = onlineUser.get(i).get("assignmentname").toString();
                if (assignmentname.contains("网格") || assignmentname.contains("铁骑") || assignmentname.contains("夜巡")) {
                    String[] split = assignmentname.split("-");
                    onlineUser.get(i).put("assignmentname", split[2]);
                } else {
                    String[] split = assignmentname.split("-");
                    onlineUser.get(i).put("assignmentname", split[1]);
                    onlineUser.get(i).put("gridding", split[0]);
                }

            }
        }
        return onlineUser;
    }


    @Override
    public ResultBeans findPostStatu(String warningSignal) {
        //签到状态  签到岗位  签到时间
        Map<String, Object> map = new HashMap<>();
        Sign sign = signMapper.selectOne(Wrappers.<Sign>lambdaQuery()
                .eq(Sign::getWarningsignal, warningSignal)
                .eq(Sign::getState, 1));

        if (sign == null) {
            return ResultUtil.resultBeansSuccess(map);
        }
        if (sign.getState() == 1) {
            map.put("state", "已签到");
            //返回签到标识和巡查id
            map.put("signnum", sign.getSignnum());
            Patrolrecord patrolRecordOne = patrolrecordMapper.findPatrolRecordOne(sign.getSignnum());
            map.put("patrolrecordId", patrolRecordOne.getSysPatrolRecordId());

        } else {
            map.put("state", "未签到");
        }
        String[] split = sign.getAssignmentname().split("-");
        map.put("assignmentname", split[split.length - 1]);
        map.put("signintime", sign.getSignintime());


        return ResultUtil.resultBeansSuccess(map);
    }

    /**
     * 当前民警已经签到 未签退的岗位
     *
     * @param warningSignal 警号
     * @return ResultBean
     */
    @Override
    public ResultBeans findPostStatus(String warningSignal, String comment) throws ParseException {
        Date date = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        // new Date()为获取当前系统 年月日 时间
        String dayTime = df.format(new Date());
        Calendar c = Calendar.getInstance();

        //-1.昨天时间 0.当前时间 1.明天时间 *以此类推
        c.add(Calendar.DATE, 1);
        String time = df.format(c.getTime());
        //平峰期下班时间
        Date closTime1 = ft.parse(dayTime + " 20:00:00");
        //平峰期下班时间
        Date closTime4 = ft.parse(dayTime + " 13:00:00");
        //高峰期下班时间
        Date closTime2 = ft.parse(dayTime + " 08:30:00");
        //高峰期下班时间
        Date closTime5 = ft.parse(dayTime + " 18:30:00");
        //高峰期下班时间
        Date closTime6 = ft.parse(dayTime + " 19:00:00");
        //夜巡下班时间 次日
        Date closTime3 = ft.parse(time + " 07:00:00");

        List<HashMap> postStatus = signMapper.findPostStatus(warningSignal, comment);
        if (postStatus.size() > 0) {
            for (int i = 0; i < postStatus.size(); i++) {
                String assignmentname = postStatus.get(i).get("assignmentname").toString();
                String assignmentid = postStatus.get(i).get("assignmentid").toString();

                if ("2".equals(postStatus.get(i).get("comment").toString())) {
                    postStatus.get(i).put("assignmentname", assignmentname);
                    postStatus.get(i).put("station", xlevelserviceMapper.findDutynameById(assignmentid));
                    postStatus.get(i).put("signouttime", "");
                    postStatus.get(i).put("state", "已签到");
                    return ResultUtil.resultBeansSuccess(postStatus);
                }
                if (assignmentname.contains("夜巡")) {
                    String[] split = assignmentname.split("-");
                    postStatus.get(i).put("assignmentname", split[1]);
                    postStatus.get(i).put("station", split[0]);
                    postStatus.get(i).put("signouttime", ft.format(closTime3));
                    postStatus.get(i).put("state", "已签到");
                    if (date.compareTo(closTime3) == 1) {
                        postStatus.get(i).put("state", "未签退");
                    } else {

                    }

                } else if (assignmentname.contains("高峰岗")) {
                    String[] split = assignmentname.split("-");
                    postStatus.get(i).put("assignmentname", split[1]);
                    postStatus.get(i).put("station", split[0]);
                    String signintime = String.valueOf(postStatus.get(i).get("signintime"));
                    Calendar cal = Calendar.getInstance();
                    int month = cal.get(Calendar.MONTH) + 1;
                    if (month == 5 || month == 6 || month == 7 || month == 8 || month == 9) {
                        if (SignTime.getEndDate(SignTime.MORING).compareTo(DateUtil.parse(signintime)) == 1) {
                            postStatus.get(i).put("signouttime", ft.format(closTime2));
                        } else {
                            postStatus.get(i).put("signouttime", ft.format(closTime6));
                        }
                    } else {
                        if (SignTime.getEndDate(SignTime.MORING).compareTo(DateUtil.parse(signintime)) == 1) {
                            postStatus.get(i).put("signouttime", ft.format(closTime2));
                        } else {
                            postStatus.get(i).put("signouttime", ft.format(closTime5));
                        }
                    }

                    if (date.compareTo(closTime2) == 1) {
                        postStatus.get(i).put("state", "未签退");
                    } else {
                        postStatus.get(i).put("state", "已签到");
                    }
                } else { //平峰期
                    String[] split = assignmentname.split("-");
                    postStatus.get(i).put("assignmentname", split[1]);
                    postStatus.get(i).put("station", split[0]);
                    String signintime = String.valueOf(postStatus.get(i).get("signintime"));
                    if (SignTime.getStartDate(AFTERNOONSESSION).after(DateUtil.parse(signintime))) {
                        postStatus.get(i).put("signouttime", ft.format(closTime4));
                    } else {
                        postStatus.get(i).put("signouttime", ft.format(closTime1));
                    }

                    if (date.compareTo(closTime1) == 1) {
                        postStatus.get(i).put("state", "未签退");
                    } else {
                        postStatus.get(i).put("state", "已签到");
                    }
                }
            }
        }
        return ResultUtil.resultBeansSuccess(postStatus);
    }


    @Override
    public ResultBeans SignInState(String warningsignal) {
        List<HashMap> postStatus = signMapper.findPostStatus(warningsignal, null);
        //判断日常还是特殊
        String comment = postStatus.get(0).get("comment").toString();
        if ("1".equals(comment)) {

        }
        return null;
    }


    @Override
    public int onlineYesterday(String battalion) {
        //昨日在线警力
        List<Map> maps = signMapper.yesterdayStrength(battalion, null);
        return maps.size();
    }


    @Override
    public List<HashMap> yesterdayData(String battalion) {

        List<HashMap> dataList = new ArrayList<>();
        HashMap<String, Object> gfData = new HashMap<>();
        gfData.put("period", "高峰期");
        HashMap<String, Object> pfData = new HashMap<>();
        pfData.put("period", "平峰期");
        HashMap<String, Object> yxData = new HashMap<>();
        yxData.put("period", "夜巡");

        if (StringUtils.isEmpty(battalion)) {
            //所有大队列表
            List<String> ddNameList = xareaMapper.findDd();

            List<HashMap> gfList = new ArrayList<>();
            List<HashMap> pfList = new ArrayList<>();
            List<HashMap> yxList = new ArrayList<>();

            for (String ddName : ddNameList) {
                HashMap<String, Object> gfDdMap = new HashMap<>();
                HashMap<String, Object> pfDdMap = new HashMap<>();
                HashMap<String, Object> yxDdMap = new HashMap<>();

                List<HashMap> gfzdList = new ArrayList<>();
                List<HashMap> pfzdList = new ArrayList<>();
                List<HashMap> yxzdList = new ArrayList<>();


                List<String> gfZdNameList = signMapper.findZdByBattalion("高峰期", ddName);
                for (String gfZdName : gfZdNameList) {
                    HashMap<String, Object> zdMap = new HashMap<>();
                    int num = signMapper.onlineYesterday("高峰期", gfZdName).size();
                    zdMap.put("lochus", gfZdName);
                    zdMap.put("num", num);

                    gfzdList.add(zdMap);
                }
                if (gfzdList.size() > 0) {
                    gfDdMap.put("data", gfzdList);
                    gfDdMap.put("battalion", ddName);
                }


                List<String> pfZdNameList = signMapper.findZdByBattalion("平峰期", ddName);
                for (String pfZdName : pfZdNameList) {
                    HashMap<String, Object> zdMap = new HashMap<>();
                    int num = signMapper.onlineYesterday("平峰期", pfZdName).size();
                    zdMap.put("lochus", pfZdName);
                    zdMap.put("num", num);
                    pfzdList.add(zdMap);
                }
                if (pfzdList.size() > 0) {
                    pfDdMap.put("data", pfzdList);
                    pfDdMap.put("battalion", ddName);
                }


                List<String> yxZdNameList = signMapper.findZdByBattalion("夜巡", ddName);
                for (String yxZdName : yxZdNameList) {
                    HashMap<String, Object> zdMap = new HashMap<>();
                    int num = signMapper.onlineYesterday("夜巡", yxZdName).size();
                    zdMap.put("lochus", yxZdName);
                    zdMap.put("num", num);

                    yxzdList.add(zdMap);
                }
                if (yxzdList.size() > 0) {
                    yxDdMap.put("data", yxzdList);
                    yxDdMap.put("battalion", ddName);
                }

                if (gfDdMap.size() > 0) {
                    gfList.add(gfDdMap);
                }
                if (pfDdMap.size() > 0) {
                    pfList.add(pfDdMap);
                }
                if (yxDdMap.size() > 0) {
                    yxList.add(yxDdMap);
                }
            }

            gfData.put("dataList", gfList);
            pfData.put("dataList", pfList);
            yxData.put("dataList", yxList);

        } else {
            List<HashMap> gfList = new ArrayList<>();
            List<HashMap> pfList = new ArrayList<>();
            List<HashMap> yxList = new ArrayList<>();

            HashMap<String, Object> gfDdMap = new HashMap<>();
            HashMap<String, Object> pfDdMap = new HashMap<>();
            HashMap<String, Object> yxDdMap = new HashMap<>();

            List<HashMap> gfzdList = new ArrayList<>();
            List<HashMap> pfzdList = new ArrayList<>();
            List<HashMap> yxzdList = new ArrayList<>();


            List<String> gfZdNameList = signMapper.findZdByBattalion("高峰期", battalion);
            for (String gfZdName : gfZdNameList) {
                HashMap<String, Object> zdMap = new HashMap<>();
                int num = signMapper.onlineYesterday("高峰期", gfZdName).size();
                zdMap.put("lochus", gfZdName);
                zdMap.put("num", num);

                gfzdList.add(zdMap);
            }
            if (gfzdList.size() > 0) {
                gfDdMap.put("data", gfzdList);
                gfDdMap.put("battalion", battalion);
            }

            List<String> pfZdNameList = signMapper.findZdByBattalion("平峰期", battalion);
            for (String pfZdName : pfZdNameList) {
                HashMap<String, Object> zdMap = new HashMap<>();
                int num = signMapper.onlineYesterday("平峰期", pfZdName).size();

                zdMap.put("lochus", pfZdName);
                zdMap.put("num", num);

                pfzdList.add(zdMap);
            }
            if (pfzdList.size() > 0) {
                pfDdMap.put("data", pfzdList);
                pfDdMap.put("battalion", battalion);
            }

            List<String> yxZdNameList = signMapper.findZdByBattalion("夜巡", battalion);
            for (String yxZdName : yxZdNameList) {
                HashMap<String, Object> zdMap = new HashMap<>();
                int num = signMapper.onlineYesterday("夜巡", yxZdName).size();

                zdMap.put("lochus", yxZdName);
                zdMap.put("num", num);

                yxzdList.add(zdMap);
            }
            if (yxzdList.size() > 0) {
                yxDdMap.put("data", yxzdList);
                yxDdMap.put("battalion", battalion);
            }
            if (gfDdMap.size() > 0) {
                gfList.add(gfDdMap);
            }
            if (pfDdMap.size() > 0) {
                pfList.add(pfDdMap);
            }
            if (yxDdMap.size() > 0) {
                yxList.add(yxDdMap);
            }

            gfData.put("dataList", gfList);
            pfData.put("dataList", pfList);
            yxData.put("dataList", yxList);
        }

        dataList.add(gfData);
        dataList.add(pfData);
        dataList.add(yxData);

        return dataList;
    }

    private ResultBeans scopeDecisions(Sign sign) {
        Integer integer = signMapper.selectCount(Wrappers.<Sign>lambdaQuery()
                .eq(Sign::getState, 1)
                .eq(Sign::getWarningsignal, sign.getWarningsignal()));
        if (integer > 0) {
            return ResultUtil.resultBeansError("您已签过到 ！", null);
        }
        String uuid = UUID.randomUUID().toString();
        sign.setSignnum(uuid);
        Patrolrecord patrolrecord = new Patrolrecord();
        patrolrecord.setSignnum(uuid);
        patrolrecord.setSysStaffId(sign.getStaffid());
        patrolrecord.setPatrolRecordBegintime(new Date());
        patrolrecord.setRoadName(sign.getAssignmentname());
        //如果是特殊勤务签到，不做时间限制
        if ("2".equals(sign.getComment())) {
            //特殊勤务，当前之能签到一个
            List<Sign> signInfoByTel = signMapper.findSignInfoByState(sign.getWarningsignal());
            if (signInfoByTel.size() > 0) {
                return ResultUtil.resultBeansError("您已签过特勤 ！", null);
            }
            //签到 特殊岗位类型
            sign.setSignintime(DateUtil.now());

            signMapper.insertSelective(sign);
            //开启巡查
            patrolrecordMapper.insertSelective(patrolrecord);

            /**
             * 特殊勤务签到后直接推送到市局平台
             * return 特勤签到推送到市局返回的qdid
             */
            String qdid = longFengService.CFqdpush(sign);

            Sign one = signMapper.selectOne(Wrappers.<Sign>lambdaQuery().eq(Sign::getSignnum, sign.getSignnum()));
            SignInfoVO signInfoVO = new SignInfoVO();

            BeanUtils.copyProperties(one, signInfoVO);
            signInfoVO.setSysPatrolRecordId(patrolrecord.getSysPatrolRecordId());

            return ResultUtil.resultBeansSuccess(signInfoVO);
        }
        //日常岗位签到，当前只能签到一个
        List<Sign> signInfoByTel = signMapper.findSignInfoByTel(sign.getWarningsignal());
        if (signInfoByTel.size() > 0) {
            return ResultUtil.resultBeansError("您已签过日常勤务", null);
        }

        sign.setSignintime(DateUtil.now());
        signMapper.insertSelective(sign);
        patrolrecordMapper.insertSelective(patrolrecord);
        Sign one = signMapper.selectOne(Wrappers.<Sign>lambdaQuery().eq(Sign::getSignnum, sign.getSignnum()));
        SignInfoVO signInfoVO = new SignInfoVO();

        BeanUtils.copyProperties(one, signInfoVO);
        signInfoVO.setSysPatrolRecordId(patrolrecord.getSysPatrolRecordId());

        return ResultUtil.resultBeansSuccess(signInfoVO);

        /*Map gate = Gate();
        //查询签到的岗位

        Xarea xarea = xareaMapper.selectByPrimaryKey(sign.getAssignmentid());


        if ("高峰岗".equals(xarea.getStation())) {
            //时间判断
            if (isEffectiveDate(new Date(), DateUtil.parse(dayTime + " " + gate.get("morningSignin")), DateUtil.parse(dayTime + " " + gate.get("morningSignout")))
                    || isEffectiveDate(new Date(), DateUtil.parse(dayTime + " " + gate.get("eveningSignin")), DateUtil.parse(dayTime + " " + gate.get("eveningSignout")))) {

                sign.setSignintime(DateUtil.now());
                signMapper.insertSelective(sign);
                patrolrecordMapper.insertSelective(patrolrecord);
                return ResultUtil.resultBeansSuccess(patrolrecord.getSysPatrolRecordId() + "," + uuid + "," + sign.getAssignmentname() + ",签到成功！");

            } else {
                return ResultUtil.resultBeansError("您不在高峰岗签到时间段内!");
            }
        } else if ("夜巡".equals(xarea.getStation())) {
            if (new Date().after(DateUtil.parse(gate.get("nightSignin").toString())) || new Date().before(DateUtil.parse(gate.get("nightSignout").toString()))) {
                //判断是否迟到  夜巡晚上八点到第二天七点
                //签到
                sign.setSignintime(DateUtil.now());
                signMapper.insertSelective(sign);
                patrolrecordMapper.insertSelective(patrolrecord);
                return ResultUtil.resultBeansSuccess(patrolrecord.getSysPatrolRecordId() + "," + uuid + "," + sign.getAssignmentname() + ",签到成功！");
            } else {
                return ResultUtil.resultBeansError("您不在夜巡签到时间段内!");
            }

        } else {
            */ /**
         * 平峰期
         * 判断是否迟到  平峰期08:30:00-17:30:00
         * 07:30:00	13:00:00
         * 13:00:00	20:00:00
         *//*
            sign.setSignintime(DateUtil.now());
            signMapper.insertSelective(sign);
            patrolrecordMapper.insertSelective(patrolrecord);
            return ResultUtil.resultBeansSuccess(patrolrecord.getSysPatrolRecordId() + "," + uuid + "," + sign.getAssignmentname() + ",签到成功！");

        }*/

    }

    //获取岗位上班时间以及签到时间
    private Map Gate() {
        //判断时间是什么时间段
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH) + 1;
        List<Gatecard> gatecardByShifop = new ArrayList<>();
        //夏季
        if (month == 5 || month == 6 || month == 7 || month == 8 || month == 9) {
            gatecardByShifop = gatecardMapper.findGatecardByShifop(1, null, 2);
        } else { //冬季出勤
            //冬季勤务模式
            gatecardByShifop = gatecardMapper.findGatecardByShifop(2, null, 2);
        }
        Map<String, Object> map = new HashMap<>();
        for (Gatecard gatecard : gatecardByShifop) {
            //早高峰出勤时间
            if (gatecard.getShiftop() == 5) {
                map.put("morningPeakStart", gatecard.getStartTime());
                map.put("morningPeakEnd", gatecard.getEndTime());
                map.put("morningSignin", gatecard.getSignin());
                map.put("morningSignout", gatecard.getSignout());

            }
            //晚高峰出勤时间
            if (gatecard.getShiftop() == 6) {
                map.put("eveningPeakStart", gatecard.getStartTime());
                map.put("eveningPeakEnd", gatecard.getEndTime());
                map.put("eveningSignin", gatecard.getSignin());
                map.put("eveningSignout", gatecard.getSignout());
            }
            //夜巡出勤
            if (gatecard.getShiftop() == 8) {
                map.put("nightTourStart", gatecard.getStartTime());
                map.put("nightTourEnd", gatecard.getEndTime());
                map.put("nightSignin", gatecard.getSignin());
                map.put("nightSignout", gatecard.getSignout());
            }

        }

        return map;

    }

    /**
     * 签到方法
     * 签到接口
     * * 07:30-08:30 早高峰
     * * 08:30-18:00 平峰（夏季）         08:30-17:30平峰 非夏季
     * * 18:00-19:00 晚高峰(夏季)         17:30-18:30晚高峰
     * * 19:00-20:00 平峰(夏季)          18:30-20:00平峰
     * * 20:00-次日7:30 夜巡
     *
     * @param sign
     * @return
     * @throws ParseException
     */
    public ResultBeans scopeDecision(Sign sign) throws ParseException {


        //如果是特殊勤务签到，不做限制
        if ("2".equals(sign.getComment())) {
            //特殊勤务，当前之能签到一个
            List<Sign> signInfoByTel = signMapper.findSignInfoByState(sign.getWarningsignal());
            if (signInfoByTel.size() > 0) {
                return ResultUtil.resultBeansError("您已签过特勤 ！");
            }
            //签到
            sign.setSignintime(DateUtil.now());
            sign.setClock("正常");
            signMapper.insertSelective(sign);
            //修改人员表警员登录状态
            Staff staff = new Staff();
            staff.setStaffOnline("1");
            staff.setSysStaffId(sign.getStaffid());
            staffMapper.updateByPrimaryKeySelective(staff);
            return ResultUtil.resultBeansSuccess(sign.getAssignmentname() + ",签到成功");
        }

        List<Sign> signInfoByTel = signMapper.findSignInfoByTel(sign.getWarningsignal());
        String[] split1 = sign.getAssignmentname().split("-");
        if (signInfoByTel.size() > 0) {
            return ResultUtil.resultBeansError("您已签过日常勤务");
        }

        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
        String dayTime = df.format(new Date());// new Date()为获取当前系统 年月日 时间
        //高峰岗签到时间(早高峰和晚高峰签到允许时间范围提早半个小时)
        //早高峰时间
        Date startTime = ft.parse(dayTime + " 07:00:00");
        Date endTime = ft.parse(dayTime + " 08:30:00");
        //晚高峰
        Date startTime2 = ft.parse(dayTime + " 17:00:00");
        Date endTime2 = ft.parse(dayTime + " 18:30:00");

        Date startTime3 = ft.parse(dayTime + " 06:30:00");
        Date endTime3 = ft.parse(dayTime + " 19:30:00");
        Date nowTime = new Date();
        /**
         * //早高峰
         */
        boolean effectiveDate = isEffectiveDate(nowTime, startTime, endTime);
        //晚高峰
        boolean effectiveDate2 = isEffectiveDate(nowTime, startTime2, endTime2);
        //白天
        boolean effectiveDate3 = isEffectiveDate(nowTime, startTime3, endTime3);

        /**
         * 非夏日时间表
         * 晚高峰   17:30-18:30
         */
        Date startTimef = ft.parse(dayTime + " 16:30:00");
        Date endTimef = ft.parse(dayTime + " 18:30:00");
        boolean effectiveDatef = isEffectiveDate(nowTime, startTimef, endTimef);
        //当前月份
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH) + 1;
        //判断是否为夏季 夏季签到时间
        if (month == 5 || month == 6 || month == 7 || month == 8 || month == 9) {
            if (effectiveDate3) {//白天(当前时间在早上7：00和晚上20：00之间)
                String[] split = sign.getAssignmentname().split("-");
                if (split[0].contains("高峰")) { //高峰期

                    if (effectiveDate || effectiveDate2) {  //高峰期都可以在这两个时间段签到
                        //签到
                        //判断是否迟到  早高峰七点半到八点半
                        Date late = ft.parse(dayTime + " 07:30:00");
                        Date date = new Date();
                        if (date.compareTo(late) == 1) {//当前时间大于07：30
                            sign.setClock("迟到");
                        } else {
                            sign.setClock("正常");
                        }
                        sign.setSignintime(DateUtil.now());
                        signMapper.insertSelective(sign);
                        //修改人员表警员登录状态
                        Staff staff = new Staff();
                        staff.setStaffOnline("1");
                        staff.setSysStaffId(sign.getStaffid());
                        staffMapper.updateByPrimaryKeySelective(staff);

                        return ResultUtil.resultBeansSuccess(sign.getAssignmentname() + ",签到成功！");
                    } else {
                        return ResultUtil.resultBeansError("您不在高峰岗签到时间段内!");
                    }
                } else if (sign.getAssignmentname().contains("夜巡")) { //夜巡
                    return ResultUtil.resultBeansError("您不在夜巡岗签到时间段内!");
                } else {   //平峰期

                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //签到
                    //判断是否迟到  平峰期
                    Date late = ft.parse(dayTime + " 07:00:00");
                    Date date = new Date();
                    if (date.compareTo(late) == 1) {//当前时间大于07：20
                        sign.setClock("迟到");
                    } else {
                        sign.setClock("正常");
                    }
                    sign.setSignintime(formatter.format(new Date()));
                    signMapper.insertSelective(sign);
                    //修改人员表警员登录状态
                    Staff staff = new Staff();
                    staff.setStaffOnline("1");
                    staff.setSysStaffId(sign.getStaffid());
                    staffMapper.updateByPrimaryKeySelective(staff);

                    return ResultUtil.resultBeansSuccess(sign.getAssignmentname() + ",签到成功！");
                }
            } else { //夜巡
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //判断是否迟到  夜巡晚上八点到第二天七点
                Date late = ft.parse(dayTime + " 20:20:00");
                Date date = new Date();
                if (date.compareTo(late) == 1) {//当前时间大于20:20:00
                    sign.setClock("迟到");
                } else {
                    sign.setClock("正常");
                }
                //签到
                sign.setSignintime(formatter.format(new Date()));
                signMapper.insertSelective(sign);
                //修改人员表警员登录状态
                Staff staff = new Staff();
                staff.setStaffOnline("1");
                staff.setSysStaffId(sign.getStaffid());
                staffMapper.updateByPrimaryKeySelective(staff);
                //return ResultUtil.setOK("success", sign.getAssignmentname() + ",签到成功！");
                return ResultUtil.resultBeansSuccess(sign.getAssignmentname() + ",签到成功！");
            }

        } else { //非夏季签到时间

            if (effectiveDate3) {//白天(当前时间在早上7：00和晚上20：00之间)
                String[] split = sign.getAssignmentname().split("-");
                if (split[0].contains("高峰")) { //高峰期
                    if (effectiveDatef || effectiveDate) {//高峰期都可以在这两个时间段签到
                        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        //签到
                        //判断是否迟到  非夏季早高峰七点半到八点半
                        System.out.println("非夏季");
                        Date late = ft.parse(dayTime + " 07:00:00");
                        Date date = new Date();
                        if (date.compareTo(late) == 1) {//当前时间大于20:20:00
                            sign.setClock("迟到");
                        } else {
                            sign.setClock("正常");
                        }
                        sign.setSignintime(formatter.format(new Date()));
                        signMapper.insertSelective(sign);
                        //修改人员表警员登录状态
                        Staff staff = new Staff();
                        staff.setStaffOnline("1");
                        staff.setSysStaffId(sign.getStaffid());
                        staffMapper.updateByPrimaryKeySelective(staff);
                        return ResultUtil.resultBeansSuccess(sign.getAssignmentname() + ",签到成功！");
                    } else {
                        return ResultUtil.resultBeansError("您不在高峰岗签到时间段内！");
                    }
                } else if (sign.getAssignmentname().contains("夜巡")) { //夜巡
                    System.out.println("白天");
                    return ResultUtil.resultBeansError("您不在夜巡岗签到时间段内！");
                } else {   //平峰期
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //签到
                    //判断是否迟到  平峰期06：30-08：00
                    System.out.println("非夏季");
                    Date late = ft.parse(dayTime + " 06:30:00");
                    Date date = new Date();
                    if (date.compareTo(late) == 1) {//当前时间大于06:30:00
                        sign.setClock("迟到");
                    } else {
                        sign.setClock("正常");
                    }
                    sign.setSignintime(formatter.format(new Date()));
                    signMapper.insertSelective(sign);
                    //修改人员表警员登录状态
                    Staff staff = new Staff();
                    staff.setStaffOnline("1");
                    staff.setSysStaffId(sign.getStaffid());
                    staffMapper.updateByPrimaryKeySelective(staff);
                    //return ResultUtil.setOK("success", sign.getAssignmentname() + ",签到成功！");
                    return ResultUtil.resultBeansSuccess(sign.getAssignmentname() + ",签到成功！");
                }
            } else { //夜巡
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //签到
                //判断是否迟到  非夏季夜巡
                System.out.println("非夏季夜巡");
                Date late = ft.parse(dayTime + " 20:20:00");
                Date date = new Date();
                if (date.compareTo(late) == 1) {//当前时间大于20:20:00
                    sign.setClock("迟到");
                } else {
                    sign.setClock("正常");
                }
                sign.setSignintime(formatter.format(new Date()));
                signMapper.insertSelective(sign);
                //修改人员表警员登录状态
                Staff staff = new Staff();
                staff.setStaffOnline("1");
                staff.setSysStaffId(sign.getStaffid());
                staffMapper.updateByPrimaryKeySelective(staff);
                return ResultUtil.resultBeansSuccess(sign.getAssignmentname() + ",签到成功！");
            }
        }
    }

    /**
     * 签到方法
     * 签到接口
     * * 07:30-08:30 早高峰
     * * 08:30-18:00 平峰（夏季）        08:30-17:30平峰 非夏季
     * * 18:00-19:00 晚高峰(夏季)        17:30-18:30晚高峰
     * * 19:00-20:00 平峰(夏季)         08:30-20:00平峰
     * * 20:00-次日7:00 夜巡
     *
     * @return
     * @throws ParseException
     */


    @Override
    public void recvMessage(String message) {
        JSONObject jsonObject = JSONObject.parseObject(message);
        String method = jsonObject.getString("method");
        //判断数据类型
        if (method.equals("signOut")) {
            //{"method":"signOut","id":"100728","gpsx":"113.678089","gpsy":"34.809136"}
            //签退
            String id = jsonObject.getString("id");
            String gpsqtx = jsonObject.getString("gpsx");
            String gpsqty = jsonObject.getString("gpsy");
            int result = signMapper.signOutById(id, DateUtil.now(), gpsqtx, gpsqty);
            if (result > 0) {
                System.out.println("签退成功");
            }

        } else if (method.equals("realTimeGPS")) {
            //实时定位信息
            Gps gps = new Gps();
            Integer staffId = staffMapper.findIdByStaffTel(jsonObject.getString("id"));
            gps.setSysStaffId(staffId);
            gps.setGpsX(jsonObject.getString("gpsx"));
            gps.setGpsY(jsonObject.getString("gpsy"));

            gps.setGpsTime(new Date());

            int result = gpsMapper.insertSelective(gps);

            if (result > 0) {
                System.out.println("获取实时GPS成功");
            } else {
                System.out.println("获取实时GPS失败");
            }
        }
    }

    @Override
    public List<Sign> findSignList(String warningsignal, String starttime, String endtime, String sectionId) {

        return signMapper.findSignList(warningsignal, starttime, endtime, sectionId);
    }

    /**
     * 车牌识别
     *
     * @param img base64 图片
     * @return
     */
    @Override
    public ResultBeans personSign(String img) {
        String url = "http://62.66.6.199:18303/rminf/pushDatas";

        HashMap<String, Object> paramMap = new HashMap<>(16);
        paramMap.put("wfxw", "1039");
        paramMap.put("wfsj", DateUtil.now());
        paramMap.put("base64Data", "data:image/jpg;base64," + img);

        String json = JSONObject.toJSONString(paramMap);
        String result = HttpRequest.post(url)
                .body(json)
                .execute().body();
        JSONObject jsonObject = JSONObject.parseObject(result);
        if ("200".equals(jsonObject.get("code"))) {
            return ResultUtil.resultBeansSuccess(jsonObject.get("data"));
        }
        log.info("车牌识别错误结果：" + result);
        return ResultUtil.resultBeansSuccess(null);
    }


    /**
     * 转base64
     */
    private static String encode(byte[] image) {
        BASE64Encoder decoder = new BASE64Encoder();
        return replaceEnter(decoder.encode(image));
    }

    private static String replaceEnter(String str) {
        String reg = "[\n-\r]";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }

    @Override
    public ResultBean personSignDetail(Integer staffId, String startDate, String endDate) {
        List<Map<String, String>> maps = signMapper.personSign(staffId, startDate, endDate);
        maps.stream().filter(x -> Strings.isEmpty(x.get("clock"))).forEach(x -> x.put("clock", "正常"));
        if (maps != null && !maps.isEmpty()) {
            return ResultUtil.setOK("success", maps);
        } else {
            return ResultUtil.setError(200, "success", "暂无数据");
        }
    }

    @Override
    public ResultBean personSignDetailByMonth(Integer staffId, String date) {
        int year;
        int month;
        //如果不传是本月
        if (Strings.isEmpty(date)) {
            year = DateUtil.thisYear();
            month = DateUtil.thisMonth();
        } else if (date.contains("-")) {
            String[] yearAndMonth = date.split("-");
            year = Integer.parseInt(yearAndMonth[0]);
            month = Integer.parseInt(yearAndMonth[1]);
        } else {
            return ResultUtil.setError(200, "日期不合法", null);
        }

        String endDate = com.zygh.lz.util.DateUtil.getLastDayOfMonth(year, month);//这个月结束
        String startDate = year + "-" + (month < 10 ? "0" + month : month) + "-01";//这个月的第一天
        List<Map<String, String>> maps = signMapper.personSign(staffId, startDate, endDate);
        maps.stream().filter(x -> Strings.isEmpty(x.get("clock"))).forEach(x -> x.put("clock", "正常"));
        if (maps != null && !maps.isEmpty()) {
            return ResultUtil.setOK("success", maps);
        } else {
            return ResultUtil.setError(200, "success", "暂无数据");
        }
    }

    /**
     * 警员月统计
     *
     * @param staffId   警号
     * @param startDate 月初
     * @param endDate   月末
     * @return
     */
    @Override
    public ResultBean personMonth(Integer staffId, String startDate, String endDate) {
        if (staffId == null || startDate == null || endDate == null) {
            return ResultUtil.setError(200, "缺少必填参数", null);
        }
        List<Map> signMonth = signMapper.personCount(staffId, startDate, endDate);
        return ResultUtil.setOK("success", signMonth);
    }

    @Override
    public ResultBeans detialMonth(Integer staffId, String date) {
        List<Map> signMonth = signMapper.personCounts(staffId, date);
        return ResultUtil.resultBeansSuccess(signMonth);
    }

    @Override
    public ResultBean signDetail(Integer staffId, String date, Integer current, Integer size) {
        PageHelper.startPage(current, size);
        List<Map> maps = signMapper.signDetail(staffId, date + "%");
        PageInfo<Map> pageInfo = new PageInfo<>(maps);
        return ResultUtil.setOK("success", pageInfo);
    }

    /**
     * 签到统计
     *
     * @param changeShifts 班次
     * @param startTime    开始时间
     * @param endTime      结束时间
     * @param stafftype    警种
     * @param sysSectionId 单位
     * @param staffNum     警号
     * @return ResultBean
     */


    /**
     * 获取工作时长
     *
     * @param maps 集合
     * @return 工作时长
     */
    private long getTime(List<Map<String, String>> maps) {
        long monute = 0;
        for (Map<String, String> one : maps) {
            try {
                String signouttime = one.get("signouttime");
                String signintime = one.get("signintime");
                if (Strings.isNotEmpty(signintime) && Strings.isNotEmpty(signouttime)) {//如果签到时间签退时间都值
                    Date signIn = DateUtil.parse(signintime);
                    Date signOut = DateUtil.parse(signouttime);
                    long between = DateUtil.between(signIn, signOut, DateUnit.MINUTE);
                    monute += between;
                }
            } catch (Exception e) {
                System.out.println("解析时间失败");
            }
        }
        return monute;
    }


    private BigDecimal getKM(List<Patrolrecord> listGps) {
        BigDecimal bigDecimal = new BigDecimal(0);

        for (Patrolrecord one : listGps) {
            //获取坐标
            List<Gps> gpsList = gpsMapper.selectGpsByRecord(one.getSysStaffId(), one.getSysPatrolRecordId());
            String allGps = gpsList.stream().map(x -> x.getCoordinate()).collect(Collectors.joining(","));

            if (Strings.isNotEmpty(allGps) && allGps.split(",").length > 2) {
                String jq = DistanceUtil.jq(allGps);
                BigDecimal km = new BigDecimal(jq);
                bigDecimal = bigDecimal.add(km);
            }
        }
        return bigDecimal;
    }

    /**
     * 时间统计+1天
     *
     * @param endTime
     * @return
     */
    private String endTime(String endTime) {
        Format f = new SimpleDateFormat("yyyy-MM-dd");
        Date sDate = DateUtil.parse(endTime, "yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(sDate);
        c.add(Calendar.DAY_OF_MONTH, 1);//利用Calendar 实现 Date日期+1天
        sDate = c.getTime();
        String format = ((SimpleDateFormat) f).format(sDate);
        return format;
    }

    /**
     * 合并两个List<Map<String,Object>>的集合
     *
     * @param m1
     * @param m2
     * @param
     * @return
     */
    private List<Map<String, Object>> merge(List<Map<String, Object>> m1, List<Map<String, Object>> m2) {
        m1.addAll(m2);
        Set<String> set = new HashSet<>();
        return m1.stream().collect(Collectors.groupingBy(o -> {
            //暂存所有key
            set.addAll(o.keySet());
            return o.get("id");
        })).entrySet().stream().map(o -> {
            //合并
            Map<String, Object> map = o.getValue().stream().flatMap(m -> {
                return m.entrySet().stream();
            }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b));
            //为没有key的赋值0
            set.stream().forEach(k -> {
                if (!map.containsKey(k))
                    map.put(k, 0);
            });
            return map;
        }).collect(Collectors.toList());

    }


    /**
     * 计算出有数据的每天有多少数据
     *
     * @param list
     * @return
     */
    private List<TreeMap<String, Object>> mkos(List<String> list) {
        List<TreeMap<String, Object>> mapList = new ArrayList<>();
        Map<String, Integer> map = new HashMap<>();
        TreeMap<String, Object> map1;
        for (String lists : list) {
            if (map.containsKey(lists)) {
                map.put(lists, map.get(lists).intValue() + 1);
            } else {
                map.put(lists, new Integer(1));
            }
        }
        Iterator<String> iter = map.keySet().iterator();
        while (iter.hasNext()) {
            map1 = new TreeMap<>();
            String key = iter.next();
            map1.put("time", key);
            map1.put("count", map.get(key));
            mapList.add(map1);
        }

        return mapList;
    }


    @Override
    public List<Sign> findOnLinker(String battalion, String station) {
        List<Sign> onLinker = signMapper.findOnLinker(battalion, station);
        if (onLinker.size() == 0) {
            return null;

        }
        onLinker.forEach(onLink -> {
            Map s = gpsMapper.RealTimeGPS(onLink.getStaffid());
            if (s != null) {
                String[] split = s.get("coordinate").toString().split(",");
                onLink.setGpsx(split[0]);
                onLink.setGpsy(split[1]);
            }
        });
        return onLinker;
    }


    /**
     * ===========================================================
     * 当班在线警力
     *
     * @return
     */

    /**
     * @param comment 1：日常勤务    2：特殊勤务
     *                onLine   入参 ：[{"station":"1","battalion":"","comment":"1"},
     *                {"station":5,"battalion":"","comment":"2"}]
     * @return
     */

    @Override
    public List<Map<String, Object>> onDutyOnLine(String onLine) {
        List<OnLine> coordinateDataList = new Gson().fromJson(onLine, new TypeToken<List<OnLine>>() {
        }.getType());
        List<Map<String, Object>> onLineInfo = new ArrayList<>();
        for (OnLine line : coordinateDataList) {
            String comment = line.getComment();
            String station = line.getStation();
            String battalion = line.getBattalion();
            if ("1".equals(comment)) {
                List<Map<String, Object>> onLinePeople = signMapper.findOnLinePeople(station, battalion);

                for (Map map1 : onLinePeople) {
                    //坐标
                    Location maps = locationMapper.findLocationEnd(Integer.valueOf(map1.get("staffid").toString()));
                    if (maps != null) {
                        //人员实时位置
                        map1.put("gpsx", maps.getLongitude());
                        map1.put("gpsy", maps.getLatitude());
                    }
                    //有无问题上报
                    List<Map> staffid = problemMapper.findProblemByAppear(Integer.valueOf(map1.get("staffid").toString()));
                    if (staffid.size() > 0) {
                        map1.put("isRead", 1);
                    } else {
                        map1.put("isRead", 0);
                    }

                }
                DistanceUtil.merge(onLineInfo, onLinePeople);
                //去重

            } else if (StrUtil.equals("2", comment)) {
                //人员详情
                List<Map<String, Object>> onLinePtrength = xlevelserviceMapper.findOnLinePtrengthPid(station, battalion);
                for (Map map1 : onLinePtrength) {
                    //人员坐标
                    String staffId = map1.get("staffid").toString();
                    Location maps = locationMapper.findLocationEnd(Integer.valueOf(staffId));
                    if (maps != null) {
                        map1.put("gpsx", maps.getLongitude());
                        map1.put("gpsy", maps.getLatitude());
                    }

                    //有无上报问题
                    List<Map> staffid = problemMapper.findProblemByAppear(Integer.valueOf(map1.get("staffid").toString()));
                    if (staffid.size() > 0) {
                        map1.put("isRead", 1);
                    } else {
                        map1.put("isRead", 0);
                    }

                }

                DistanceUtil.merge(onLineInfo, onLinePtrength);
                //return onLineSecret;
            } else {
                return null;
                /*//查询所有在线警力 先查岗位--》在线人
                //人员详情
                List<Map<String, Object>> maps = signMapper.OnlineStaff(battalion);
                for (Map map : maps) {
                    String id = map.get("staffid").toString();
                    String warningsignal = map.get("warningsignal").toString();
                    //Location gps = locationMapper.findLocationEnd(Integer.valueOf(id));
                    Equipage gps = equipageMapper.findEquipageEnd(warningsignal);
                    if (gps != null && !"".equals(gps)) {
                        map.put("gpsx", gps.getLongitude());
                        map.put("gpsy", gps.getLatitude());
                        //map.put("direction", gps.getDirection());
                    }
                    List<Map> staffid = problemMapper.findProblemByAppear(Integer.valueOf(id));
                    if (staffid.size() > 0) {
                        map.put("isRead", 1);
                    } else {
                        map.put("isRead", 0);
                    }
                }
                DistanceUtil.merge(onLineInfo, maps);*/
            }


        }
        return onLineInfo;

    }

    /*@Override
    public List<Map<String, Object>> onDutyOnLine(String onLine) {
        List<OnLine> coordinateDataList = new Gson().fromJson(onLine, new TypeToken<List<OnLine>>() {
        }.getType());
        List<Map<String, Object>> onLineInfo = new ArrayList<>();
        for (OnLine line : coordinateDataList) {
            String comment = line.getComment();
            String station = line.getStation();
            String battalion = line.getBattalion();
            if ("1".equals(comment)) {
                //取所有岗位
                List<Map<String, Object>> onLineSign = signMapper.findOnLineSign(station, battalion);
                for (Map map : onLineSign) {
                    //人员详情
                    List<Map> onLineStrength = signMapper.findOnLineStrength(map.get("station").toString(),
                            Integer.valueOf(map.get("assignmentid").toString()), battalion, null);
                    for (Map map1 : onLineStrength) {
                        Location maps = locationMapper.findLocationEnd(Integer.valueOf(map1.get("staffid").toString()));
                        //Equipage maps = equipageMapper.findEquipageEnd(map1.get("warningsignal").toString());
                        List<Map> staffid = problemMapper.findProblemByAppear(Integer.valueOf(map1.get("staffid").toString()));
                        if (staffid.size() > 0) {
                            map1.put("isRead", 1);
                        } else {
                            map1.put("isRead", 0);
                        }

                        if (maps != null) {
                            //人员实时位置
                            //String[] split = maps.get("coordinate").toString().split(",");
                            map1.put("gpsx", maps.getLongitude());
                            map1.put("gpsy", maps.getLatitude());
                            //map1.put("direction", maps.getDirection());

                        }
                    }
                    map.put("detail", onLineStrength);
                }
                DistanceUtil.merge(onLineInfo, onLineSign);
                //去重

            } else if (StrUtil.equals("2", comment)) {
                List<Map<String, Object>> onLineSecret = xlevelserviceMapper.findOnLineSecret(station, battalion);
                for (Map map : onLineSecret) {
                    //人员详情
                    List<Map> onLinePtrength = xlevelserviceMapper.findOnLinePtrengthPid(station, Integer.valueOf(map.get("assignmentid").toString()), battalion);
                    for (Map map1 : onLinePtrength) {
                        //String warningsignal = map1.get("warningsignal").toString();
                        String staffId = map1.get("staffid").toString();
                        Location maps = locationMapper.findLocationEnd(Integer.valueOf(staffId));
                        //Equipage maps = equipageMapper.findEquipageEnd(warningsignal);
                        List<Map> staffid = problemMapper.findProblemByAppear(Integer.valueOf(map1.get("staffid").toString()));
                        if (staffid.size() > 0) {
                            map1.put("isRead", 1);
                        } else {
                            map1.put("isRead", 0);
                        }
                        if (maps != null) {
                            map1.put("gpsx", maps.getLongitude());
                            map1.put("gpsy", maps.getLatitude());
                            //map1.put("direction", maps.getDirection());
                        }
                    }
                    map.put("detail", onLinePtrength);

                }
                DistanceUtil.merge(onLineInfo, onLineSecret);
                //return onLineSecret;
            } else {
                //查询所有在线警力 先查岗位--》在线人
                //人员详情
                List<Map<String, Object>> maps = signMapper.OnlineStaff(battalion);
                for (Map map : maps) {
                    String id = map.get("staffid").toString();
                    String warningsignal = map.get("warningsignal").toString();
                    //Location gps = locationMapper.findLocationEnd(Integer.valueOf(id));
                    Equipage gps = equipageMapper.findEquipageEnd(warningsignal);
                    if (gps != null && !"".equals(gps)) {
                        map.put("gpsx", gps.getLongitude());
                        map.put("gpsy", gps.getLatitude());
                        //map.put("direction", gps.getDirection());
                    }
                    List<Map> staffid = problemMapper.findProblemByAppear(Integer.valueOf(id));
                    if (staffid.size() > 0) {
                        map.put("isRead", 1);
                    } else {
                        map.put("isRead", 0);
                    }
                }
                DistanceUtil.merge(onLineInfo, maps);
            }


        }
        return onLineInfo;

    }*/

    @Override
    public List<Map> yesterdayOnLine(String battalion) {
        //昨日在线全部部门
        List<Map> maps = signMapper.yesterdayBranch(battalion);
        for (Map map : maps) {
            //在线警力
            List<Map> maps1 = signMapper.yesterdayStrength(map.get("sectionName").toString(), null);
            map.put("number", maps1.size());
            //班次
            List<Map> classes = signMapper.yesterdayClasses(map.get("sectionName").toString());
            //本大队班次下的警力shiftop
            for (Map aClass : classes) {
                List<Map> strength = signMapper.yesterdayStrength(map.get("sectionName").toString(), aClass.get("shiftop").toString());
                aClass.put("strength", strength);
            }
            map.put("classes", classes);
        }
        return maps;
    }

    @Override
    public List<Map> yesterdaySignStation(String staffid, String shiftop) {
        List<Map> maps = signMapper.yesterdaySignStation(staffid, shiftop);
        return maps;
    }


    /**
     * 签到数=正常签到数（高峰岗大于30分钟，其他大于2小时，包含迟到早退的签到；只要达到时长都算签到数）
     * ======================================签到统计====================================================
     */

    /**
     * 按照岗位、时间、班次统计
     *
     * @param sectionId 大队id
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param shiftop   班次
     * @return List<Map>
     */

    @Override
    public Map signInStatistics(Integer sectionId, String startTime, String endTime, Integer modeCode) {
        Map map = new HashMap();
        //签到数据 (所有的签到数，其中包括迟到早退的)  签到人数
        List<Map> maps = signMapper.signInAfew(sectionId, startTime, endTime, modeCode, null);
        //迟到 支队机关不统计迟到早退
        //迟到
        List<Map> lateData = maps.stream().filter(x -> Strings.isNotEmpty(x.get("clock") == null ? "" : x.get("clock").toString())).filter(x -> "迟到".equals(x.get("clock")) & !"75".equals(x.get("sectionPid"))).collect(Collectors.toList());
        //早退
        List<Map> leaveData = maps.stream().filter(x -> Strings.isNotEmpty(x.get("clock") == null ? "" : x.get("clock").toString())).filter(x -> "早退".equals(x.get("clock")) & !"75".equals(x.get("sectionPid"))).collect(Collectors.toList());

        /**
         * ===================计算签到率==============
         * 签到率=签到数 / 应签到人数（每个岗位应签到多少人）
         */
        if (startTime == null && endTime == null) {
            startTime = DateUtil.yesterday().toString();
            endTime = DateUtil.now();
        }
        Date startTimes = DateUtil.parse(startTime);
        Date endTimes = DateUtil.parse(endTime);


        //一天应签到人次
        long rday = xareaMapper.findShouldSum(sectionId, null, modeCode).size();
        long days = DateUtil.between(startTimes, endTimes, DateUnit.DAY) + 1;
        //岗位数（白天岗位数（高速/高架除外）*2（上午班/下午班）+夜巡的岗位数）
        //签到率=签到数/应签到人次（每个岗位应签到多少人）* 天数
        long days1 = rday * days;
        double percent = maps.size() / (double) days1 * 100;
        //签到数
        map.put("signInAfew", maps.size());
        //迟到
        map.put("lateData", lateData.size());
        //早退
        map.put("leaveData", leaveData.size());
        //签到率
        map.put("signInRate", percent);
        //漏签数
        // map.put("leakageSign", leakageSign.size());
        return map;
    }


    /**
     * 按照岗位、时间、班次统计每个大队人数及详情
     *
     * @param sectionId 大队id
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param shiftop   班次
     * @return List<Map>
     */
    @Override
    public List<Map> signInDetail2(HttpServletRequest request, Integer sectionId, String startTime, String endTime, Integer shiftop) {
        Integer sectionId1 = getSectionId(request);
        if (Objects.isNull(sectionId1)) {
            List<Map> maps = sectionMapper.findSectionDid(sectionId);
            if (Objects.isNull(maps)) {
                return new ArrayList<>();
            }
            maps.forEach(map -> {
                //签到数的详情
                //日常
                List<Map<String, Object>> sectionpid = signMapper.signInDetail2(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, shiftop);

                List<Map<String, Object>> data = new ArrayList<>();
                List<DutyModel> dutyModels = dutyModelMapper.selectList(Wrappers.emptyWrapper());
                dutyModels.forEach(x -> {
                            Map<String, Object> da = new HashMap<>();
                            da.put("classes", x.getName());
                            da.put("countSize", 0);
                            da.put("shiftop", x.getCode());
                            Optional<Integer> mode_code = sectionpid.stream().filter(y -> Objects.nonNull(y.get("mode_code"))).map(y -> (int) y.get("mode_code")).filter(t -> t == x.getCode()).findFirst();
                            if (mode_code.isPresent()) {
                                Optional<Map<String, Object>> mode_code1 = sectionpid.stream().filter(y -> Objects.nonNull(y.get("mode_code"))).filter(y -> y.get("mode_code").equals(mode_code.get())).findAny();
                                da.put("countSize", mode_code1.get().get("countSize"));
                            }
                            if (StrUtil.equals(x.getName(), "特勤")) {
                                Integer tqSection = signMapper.signInDetail3(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, shiftop);
                                da.put("countSize", tqSection);
                            }
                            data.add(da);
                        }

                );
                map.put("classes", data);
            });
            return maps;
        }
        //大队权限
        List<Map> maps = sectionMapper.findSection(sectionId1);
        System.out.println("maps:" + maps.toString());
        maps.forEach(map -> {

            System.out.println("=============================");
            System.out.println("map.get(sectionpid):" + map.get("section_pid"));
            System.out.println("=============================");
            //List<Map<String, Object>> sectionpid = signMapper.signInDetail2(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null);
            List<Map<String, Object>> sectionpid = signMapper.signInDetail2(Integer.valueOf(map.get("section_pid").toString()), startTime, endTime, null);
            List<Map<String, Object>> data = new ArrayList<>();
            List<DutyModel> dutyModels = dutyModelMapper.selectList(Wrappers.emptyWrapper());
            dutyModels.forEach(x -> {
                        Map<String, Object> da = new HashMap<>();
                        da.put("classes", x.getName());
                        da.put("countSize", 0);
                        da.put("modeCode", x.getCode());
                        Optional<Integer> mode_code = sectionpid.stream().filter(y -> Objects.nonNull(y.get("mode_code"))).map(y -> (int) y.get("mode_code")).filter(t -> t == x.getCode()).findFirst();
                        if (mode_code.isPresent()) {
                            Optional<Map<String, Object>> mode_code1 = sectionpid.stream().filter(y -> Objects.nonNull(y.get("mode_code"))).filter(y -> y.get("mode_code").equals(mode_code.get())).findAny();
                            da.put("countSize", mode_code1.get().get("countSize"));
                        }
                        data.add(da);
                    }

            );
            map.put("classes", data);
        });
        return maps;
    }

    @Override
    public void dailyService(HttpServletResponse response) {
        String title = "交警勤务岗位统计表";
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.setSheet(0).renameSheet("交警勤务岗位统计表");

        //所有支队下各岗位的岗位数量和每班次警力配置
        List<Map<String, Object>> list = xareaMapper.selectDailyService();
        //获取需统计的各支队
        List<String> battalionList = list.stream().map(x -> x.get("battalion").toString()).collect(Collectors.toList());

        //获取需统计的各岗位类型
        List<String> postList = list.stream().map(x -> x.get("station").toString()).distinct().collect(Collectors.toList());
        int size = postList.size();

        Map<Object, List<Map<String, Object>>> stationMap = list.stream().filter(x -> battalionList.contains(x.get("battalion"))).collect(Collectors.groupingBy(x -> x.get("station")));

        writer.merge(0, 0, 0, size * 2 + 3, title, true);
        writer.merge(0, 0, size * 2 + 5, size * 2 + 6, "平峰期", true);
        writer.merge(0, 0, size * 2 + 7, size * 2 + 8, "高峰期", true);
        writer.merge(0, 0, size * 2 + 9, size * 2 + 10, "夜间", true);
        //设置标题行属性
        writer.setRowHeight(0, 40);

        writer.writeCellValue(1, 1, "总岗位");
        //平峰，高峰，夜间下的应签警力和岗位
        for (int i = 5; i < 11; i++) {
            if (i % 2 == 0) {
                writer.writeCellValue(size * 2 + i, 1, "应签");
            } else {
                writer.writeCellValue(size * 2 + i, 1, "岗位");
            }
            writer.writeCellValue(size * 2 + i, 2, null);
        }
        //各支队的部门id去重
        List<String> sectionDidList = list.stream().map(x -> x.get("sectionDid").toString()).distinct().collect(Collectors.toList());
        int cellY = 2;
        int hiramineSumPost = 0;   //平峰期应签岗位
        int hiramineSumPeopel = 0; //平峰期应签警力
        int peakSumPost = 0;
        int peakSumPeopel = 0;
        int nightSumPost = 0;
        int nightSumPeopel = 0;
        for (String sectionDid : sectionDidList) {
            cellY++;
            //平峰期下的应签岗位和警力
            int[] hiraminePost = {2, 3, 5, 6, 7};
            Map<String, Integer> hiramineCount = xareaMapper.getPingCount(sectionDid, hiraminePost);
            int post1 = Integer.valueOf(String.valueOf(hiramineCount.get("post")));
            int peopel1 = Integer.valueOf(String.valueOf(hiramineCount.get("peopel")));
            writer.writeCellValue(size * 2 + 5, cellY, post1);  //应签岗位
            hiramineSumPost += post1;
            writer.writeCellValue(size * 2 + 6, cellY, peopel1);  //应签警力
            hiramineSumPeopel += peopel1;

            //高峰期下的应签岗位和警力
            int[] peakPost = {1, 2, 3, 5, 6, 7};
            Map<String, Integer> peakCount = xareaMapper.getPingCount(sectionDid, peakPost);
            int post2 = Integer.valueOf(String.valueOf(peakCount.get("post")));
            int peopel2 = Integer.valueOf(String.valueOf(peakCount.get("peopel")));
            writer.writeCellValue(size * 2 + 7, cellY, post2);  //应签岗位
            peakSumPost += post2;
            writer.writeCellValue(size * 2 + 8, cellY, peopel2);  //应签警力
            peakSumPeopel += peopel2;

            //夜间的应签岗位和警力
            int[] nightPost = {4};
            Map<String, Integer> nightCount = xareaMapper.getPingCount(sectionDid, nightPost);
            int post3 = Integer.valueOf(String.valueOf(nightCount.get("post")));
            int peopel3 = Integer.valueOf(String.valueOf(nightCount.get("peopel")));
            writer.writeCellValue(size * 2 + 9, cellY, post3);  //应签岗位
            nightSumPost += post3;
            writer.writeCellValue(size * 2 + 10, cellY, peopel3);  //应签警力
            nightSumPeopel += peopel3;
        }
        writer.writeCellValue(size * 2 + 5, cellY + 1, hiramineSumPost); //平峰期总岗位
        writer.writeCellValue(size * 2 + 6, cellY + 1, hiramineSumPeopel); //平峰期总警力
        writer.writeCellValue(size * 2 + 7, cellY + 1, peakSumPost);
        writer.writeCellValue(size * 2 + 8, cellY + 1, peakSumPeopel);
        writer.writeCellValue(size * 2 + 9, cellY + 1, nightSumPost);
        writer.writeCellValue(size * 2 + 10, cellY + 1, nightSumPeopel);


        writer.merge(1, 1, 2, 3, "每日部署警力", false);

        ArrayList<String> stringArr = CollUtil.newArrayList("", "", "", "");
        for (int i = 0; i < stationMap.keySet().size(); i++) {
            stringArr.add("岗位");
            stringArr.add("每班次警力");
        }

        for (int i = 0; i < stringArr.size(); i++) {
            writer.writeCellValue(i, 2, stringArr.get(i));
        }
        List<String> xx = new ArrayList<>(10);
        List<String> y = new ArrayList<>(10);

        AtomicInteger j = new AtomicInteger(4);
        //总计总岗位
        AtomicInteger sumPost = new AtomicInteger();
        //总计每日部署警力
        AtomicInteger sumPeople = new AtomicInteger();

        AtomicInteger sumIndex = new AtomicInteger(3);
        Map<Object, List<Map<String, Object>>> battalion = list.stream().filter(x -> Objects.nonNull(x.get("battalion"))).collect(Collectors.groupingBy(x -> x.get("battalion")));

        Map<Object, List<Map<String, Object>>> battalionMap = new LinkedHashMap<>();

        for (String s : battalionList) {
            battalionMap.put(s, battalion.get(s));
        }

        battalionMap.forEach((k, v) -> {
            //岗位数
            int postSum = v.stream().mapToInt(x -> Integer.valueOf(String.valueOf(x.get("post")))).sum();
            //警力数
            int peopleSum = v.stream().filter(x -> Objects.nonNull(x.get("people"))).mapToInt(x -> Integer.valueOf(String.valueOf(x.get("people")))).sum();
            sumPost.addAndGet(postSum);
            sumPeople.addAndGet(peopleSum);
            //sumIndex.get()；3
            writer.writeCellValue(1, sumIndex.get(), postSum);
            //writer.merge(sumIndex.get(), sumIndex.get(), 2, 3, peopleSum, false);
            //每日部署警力下的数量
            writer.merge(sumIndex.get(), sumIndex.get(), 2, 3, null, false);
            writer.writeCellValue(0, sumIndex.get(), k);

            //相当于++，从3开始加
            sumIndex.getAndIncrement();

            y.add(String.valueOf(k));
        });
        Map<Object, List<Map<String, Object>>> sortPostMap = new LinkedHashMap<>();

        for (String s : postList) {
            sortPostMap.put(s, stationMap.get(s));
        }
        sortPostMap.forEach((kk, vv) -> {
            if (Objects.isNull(vv)) {
                return;
            }
            writer.merge(1, 1, j.get(), j.get() + 1, kk, false);
            //总计 固定岗，高峰岗 。。。
            int peopleSum = vv.stream().mapToInt(x -> Integer.valueOf(x.getOrDefault("people", 0).toString())).sum();
            int postSum = vv.stream().mapToInt(x -> Integer.valueOf(x.getOrDefault("post", 0).toString())).sum();

            writer.writeCellValue(j.get(), y.size() + 3, postSum);
            writer.writeCellValue(j.get() + 1, y.size() + 3, peopleSum);

            j.addAndGet(2);
            xx.add(String.valueOf(kk));
        });

        for (Map<String, Object> map : list) {
            int indexX = xx.indexOf(String.valueOf(map.get("station")));
            int indexY = y.indexOf(String.valueOf(map.get("battalion")));
            if (indexX == -1 || indexY == -1) {
                continue;
            }
            writer.writeCellValue(2 * indexX + 4, indexY + 3, map.get("post"));
            writer.writeCellValue(2 * indexX + 5, indexY + 3, String.valueOf(map.get("people")));
        }

        writer.writeCellValue(0, y.size() + 3, "总计");
        writer.writeCellValue(1, y.size() + 3, sumPost.get());
        writer.merge(y.size() + 3, y.size() + 3, 2, 3, null, false);
        //writer.merge(y.size() + 3, y.size() + 3, 2, 3, sumPeople.get(), false);


        //设置标题行属性
        writer.setRowHeight(1, 40);


        //设置边框属性
        for (int i = 0; i < xx.size() + 13; i++) {
            for (int yy = 0; yy < y.size() + 4; yy++) {
                CellStyle cellStyle = writer.createCellStyle(i, yy);
                cellStyle.setBorderBottom(BorderStyle.THIN);
                cellStyle.setBorderLeft(BorderStyle.THIN);
                cellStyle.setBorderRight(BorderStyle.THIN);
                cellStyle.setBorderTop(BorderStyle.THIN);
                cellStyle.setAlignment(HorizontalAlignment.LEFT);
                if (yy == 1 || yy == 0) {
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                }
            }
        }

        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=out.xls");
            ServletOutputStream out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (Exception e) {
            log.error("读取excel异常", e);
        }
    }

    @Override
    public ResultBean getPushSingData() {
        return ResultUtil.setOK("success", signMapper.findSignListByCfstatus());
    }

    @Override
    public List<Integer> getTodaySignInPostId(Integer type) {
        return signMapper.getTodaySignInPostId(type);
    }

    @Override
    public List<Map> signInDetail(Integer sectionId, String startTime, String endTime, Integer shiftop) {
        //包含的大队
        //List<Map> maps = signMapper.signInNumber(sectionId, startTime, endTime, shiftop, null);
        List<Map> maps = sectionMapper.findSectionDid(sectionId);
        maps.forEach(map -> {
            //签到数的详情
            //日常
            List<Map> signInAfew = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, shiftop, 1);
            //特勤
            List<Map> signInAfewtq = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, 2);
            //大队包含班次数量
            map.put("signInAfew", signInAfew.size() + signInAfewtq.size());
            //班次
            List<Map> allClassses = classesMapper.findAllClassses();

            map.put("classes", allClassses);

            //班次下包含的人员 特殊岗单独加
            allClassses.forEach(signIn -> {
                if (Integer.valueOf(signIn.get("shiftop").toString()) == 5) {
                    //特勤人员
                    List<Map> signInAfews = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, 2);
                    signIn.put("detail", signInAfews);
                    //加入该警员的签到岗位
                    merges(signInAfews);
                } else {
                    //人员
                    List<Map> signInAfews = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, Integer.valueOf(signIn.get("shiftop").toString()), 1);
                    signIn.put("detail", signInAfews);
                    //加入该警员的签到岗位
                    merges(signInAfew);

                }

            });
        });
        return maps;
    }


    /**
     * 合计 按照岗位、时间、班次统计每个中队人数及详情
     *
     * @param sectionDId
     * @param startTime
     * @param endTime
     * @param shiftop
     * @return
     */
    @Override
    public List<Map> signInDetailByLochus(Integer sectionDId, String startTime, String endTime, Integer shiftop) {
        //签到统计所有签到的中队
        //List<Map> mapList = signMapper.signInAfewLochus(sectionId, startTime, endTime, shiftop, comment);
        List<Map> mapList = sectionMapper.findSectionZid(sectionDId);
        for (Map map : mapList) {
            //中队签到人数
            List<Map> signSum = signMapper.signInStaffLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, null);
            map.put("signInAfew", signSum.size());

            //中队下包含的签到班次
            List<Map> allClassses = classesMapper.findAllClassses();
            for (Map allClasss : allClassses) {
                if (Integer.valueOf(allClasss.get("shiftop").toString()) == 5) {
                    //中队下签到的人员信息
                    List<Map> mapList1 = signMapper.signInStaffLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, 2);
                    allClasss.put("detail", mapList1);
                    allClasss.put("signInAfew", mapList1.size());
                    //加入该警员的签到岗位
                    merges(mapList1);
                } else {
                    //中队下签到的人员信息
                    List<Map> mapList1 = signMapper.signInStaffLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, Integer.valueOf(allClasss.get("shiftop").toString()), 1);
                    allClasss.put("detail", mapList1);
                    allClasss.put("signInAfew", mapList1.size());
                    //加入该警员的签到岗位
                    merges(mapList1);
                }


            }
            map.put("classes", allClassses);
        }
        return mapList;

    }

    @Override
    public List<Map<String, Object>> signInByLochus(Integer sectionDId, Integer sectionId, String startTime, String endTime, Integer shiftop) {
        Integer comment = null;
        if (shiftop != null) {
            if (shiftop == 5) {
                shiftop = null;
                comment = 2;
            } else {
                comment = 1;
            }
        }
        //签到统计查询所有签到大队下 所签到的中队
        //如果comment=null  大队=日常+特勤
        List<Map<String, Object>> merge = new ArrayList<>();
        if (comment == null) {
            List<Map<String, Object>> maps = signMapper.signInAfewLochus(sectionDId, sectionId, startTime, endTime, shiftop, 1);
            List<Map<String, Object>> mapt = signMapper.signInSpecialNumberLochus(sectionDId, sectionId, startTime, endTime, shiftop, 2);
            merge = DistanceUtil.merge(maps, mapt);
        } else {
            if (shiftop == null) {
                merge = signMapper.signInSpecialNumberLochus(sectionDId, sectionId, startTime, endTime, shiftop, 2);
            } else {
                merge = signMapper.signInAfewLochus(sectionDId, sectionId, startTime, endTime, shiftop, comment);
            }
        }
        for (Map map : merge) {
            if (map.get("shiftop") == null) {
                shiftop = null;
            } else {
                shiftop = Integer.valueOf(map.get("shiftop").toString());
            }
            //中队签到人数
            List<Map> mapList1 = signMapper.signInStaffLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, shiftop, Integer.valueOf(map.get("comment").toString()));
            map.put("signInAfew", mapList1.size());
            //中队下签到的人员信息
            //巡查时长和里程
            for (Map signInAfew : mapList1) {
                Map map1 = duration(Integer.valueOf(signInAfew.get("staffid").toString()), startTime, endTime);
                signInAfew.put("duration", map1.get("duration"));
                signInAfew.put("mileages", map1.get("mileages"));
            }
            //加入该警员的签到岗位
            merges(mapList1);
            map.put("detail", mapList1);
        }
        return merge;

    }

    //加入该警员的签到岗位
    private void merges(List<Map> mapList1) {
        mapList1.forEach(signIns -> {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String signintime = signIns.get("signintime").toString();
            //String signouttime = signIns.get("signouttime").toString();
            Date startdate = null;
            Date enddate = null;
            try {
                startdate = simpleDateFormat.parse(signintime);
                //enddate = simpleDateFormat.parse(signouttime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            //一天的起始时间
            String signintimes = simpleDateFormat.format(startdate) + " 00:00:00";
            String signouttimes = simpleDateFormat.format(startdate) + " 23:59:59";
            Integer shiftop = null;
            Integer comment = null;
            if (signIns.get("comment") != null && Integer.valueOf(signIns.get("comment").toString()) == 2) {
                shiftop = null;
                comment = 2;
            } else {
                shiftop = Integer.valueOf(signIns.get("shiftop").toString());
                comment = Integer.valueOf(signIns.get("comment").toString());
            }
            List<Map> mapList2 = signMapper.signInStation(Integer.valueOf(signIns.get("staffid").toString()), signintimes, signouttimes, shiftop, comment);
            signIns.put("detail", mapList2);

        });
    }


    //计算时长和巡查里程
    public Map duration(Integer staffId, String startDate, String endDate) {
        //List<Patrolrecord> patrolrecords = patrolrecordMapper.countKms(staffId, startDate, endDate);
        List<Map<String, Object>> signById = signMapper.findSignById(staffId, startDate, endDate);
        //巡查分钟
        int duration = 0;
        double mileages = 0;
        long dura = 0;
        for (Map<String, Object> map : signById) {
            Date date = new Date();
            //上班时长
            if (StringUtils.isEmpty(map.get("signouttime").toString())) {
                dura = DataTime.getDateduration(date, DateUtil.parseDateTime(map.get("signintime").toString()));
            } else {
                dura = DataTime.getDateduration(DateUtil.parseDateTime(map.get("signouttime").toString()), DateUtil.parseDateTime(map.get("signintime").toString()));
            }
            duration += dura;
            mileages += gpsMapper.findMileages(map.get("signnum").toString());
        }
        /*for (Patrolrecord patrolrecord : patrolrecords) {
            Date date = new Date();
            //上班时长
            if (patrolrecord.getPatrolRecordEndtime() == null) {
                dura = DataTime.getDateduration(date, patrolrecord.getPatrolRecordBegintime());
            } else {
                dura = DataTime.getDateduration(patrolrecord.getPatrolRecordEndtime(), patrolrecord.getPatrolRecordBegintime());
            }
            duration += dura;
            mileages += gpsMapper.findMileages(patrolrecord.getSignnum());
        }*/
        //米换算成公里
        DecimalFormat df = new DecimalFormat("#0.0");
        DecimalFormat decimalFormat = new DecimalFormat("#");

        //分钟转小时
        long hour = duration / 60;
        //分钟
        long min = duration % 60;
        Map map = new HashMap();
        map.put("duration", hour + "小时" + min + "分钟");

        map.put("mileages", df.format(mileages / 1000));
        map.put("hour", hour);
        map.put("kilometre", decimalFormat.format(mileages / 1000));
        return map;
    }


    @Override
    public List<Map> SignDetailByStation(Integer sectionId, String startTime, String endTime) {
        //包含的大队
        List<Map> maps = sectionMapper.findSectionDid(sectionId);
        for (Map map : maps) {
            //查询所有日常人数
            List<Map> signInAfew1 = signMapper.SignInStationInfo(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, 3);
            //查询所有特勤人数
            List<Map> signInAfew = signMapper.SignInStationInfo(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, 2);
            map.put("signInAfew", signInAfew.size() + signInAfew1.size());
            //岗位
            List<Map> allStation = stationMapper.findAllStation();
            map.put("classes", allStation);
            for (Map map1 : allStation) {
                String station = map1.get("classes").toString();
                Integer comment = 1;
                if (station.equals("特勤")) {
                    comment = 2;
                    station = null;
                }
                //人员
                List<Map> maps1 = signMapper.SignInStationInfo(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, station, comment);
                map1.put("detail", maps1);
            }
        }
        return maps;

    }

    @Override
    public List<Map> SignDetailByStationLochus(Integer sectionId, String startTime, String endTime, String station) {
        //包含的中队
        //List<Map> maps = signMapper.signInNumber(sectionId, startTime, endTime, null, comment);
        List<Map> mapList = sectionMapper.findSectionZid(sectionId);
        Integer comment = null;
        for (Map map : mapList) {
            //中队下人员
            List<Map> signInAfew = signMapper.SignInStationLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, null);
            map.put("signInAfew", signInAfew.size());
            //中队下包含的岗位岗位
            List<Map> allStation = stationMapper.findAllStation();
            map.put("classes", allStation);
            //List<Map> allStation = xareaMapper.finSStationBysectionId(Integer.valueOf(mapz.get("sectionId").toString()),station);
            for (Map map1 : allStation) {
                if ("特勤".equals(map1.get("classes").toString())) {
                    station = null;
                    comment = 2;
                } else {
                    station = map1.get("classes").toString();
                    comment = 1;
                }
                //中队下人员
                List<Map> maps1 = signMapper.SignInStationLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, station, comment);
                map1.put("detail", maps1);
            }

        }
        return mapList;
    }

    @Override
    public List<Map<String, Object>> SignByStationLochus(Integer sectionDId, Integer sectionId, String startTime, String endTime, String station) {
        Integer comment = null;
        if (StringUtils.isNotEmpty(station)) {
            if ("特勤".equals(station)) {
                station = null;
                comment = 2;
            } else {
                comment = 1;
            }
        }
        //包含的中队
        List<Map<String, Object>> mapList = signMapper.signInSpecialDetailLochus(sectionDId, sectionId, startTime, endTime, station, comment);
        for (Map map : mapList) {
            if ("特勤".equals(map.get("class").toString())) {
                station = null;
            } else {
                station = map.get("class").toString();
            }
            //中队下人员
            List<Map> maps1 = signMapper.SignInStationLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, station, Integer.valueOf(map.get("comment").toString()));
            //巡查时长和里程
            for (Map signInAfew : maps1) {
                Map map1 = duration(Integer.valueOf(signInAfew.get("staffid").toString()), startTime, endTime);
                signInAfew.put("duration", map1.get("duration"));
                signInAfew.put("mileages", map1.get("mileages"));
            }
            map.put("signInAfew", maps1.size());
            map.put("detail", maps1);

        }
        return mapList;
    }


    @Override
    public List<Map<String, Object>> SignInStatistics(Integer sectionId, String startTime, String endTime, Integer shiftop) {
        Integer comment = null;
        if (shiftop != null) {
            if (shiftop == 5) {
                shiftop = null;
                comment = 2;
            } else {
                comment = 1;
            }
        }
        //大队
        //如果comment=null  大队=日常+特勤
        List<Map<String, Object>> merge = new ArrayList<>();
        if (comment == null) {
            List<Map<String, Object>> maps = signMapper.signInNumbers(sectionId, startTime, endTime, shiftop, 1);
            List<Map<String, Object>> mapt = signMapper.signInSpecialNumbers(sectionId, startTime, endTime, shiftop, 2);
            merge = DistanceUtil.merge(maps, mapt);
        } else {
            if (shiftop == null) {
                merge = signMapper.signInSpecialNumbers(sectionId, startTime, endTime, shiftop, 2);
            } else {
                merge = signMapper.signInNumbers(sectionId, startTime, endTime, shiftop, comment);
            }
        }
        //人员信息
        for (Map<String, Object> map : merge) {
            if (map.get("shiftop") == null) {
                shiftop = null;
            } else {
                shiftop = Integer.valueOf(map.get("shiftop").toString());
            }

            //人员
            List<Map> signInAfews = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, shiftop, Integer.valueOf(map.get("comment").toString()));
            //巡查时长和里程
            for (Map signInAfew : signInAfews) {
                Map map1 = duration(Integer.valueOf(signInAfew.get("staffid").toString()), startTime, endTime);
                signInAfew.put("duration", map1.get("duration"));
                signInAfew.put("mileages", map1.get("mileages"));
            }
            map.put("signInAfew", signInAfews.size());
            map.put("detail", signInAfews);
            //加入该警员的签到岗位
            merges(signInAfews);
        }
        return merge;

    }

    @Override
    public List<Map<String, Object>> SignInStationByDetail(Integer sectionId, String startTime, String endTime, String station) {
        Integer comment = null;
        if (StringUtils.isNotEmpty(station)) {
            System.out.println("--");
            if ("特勤".equals(station)) {
                station = null;
                comment = 2;
            } else {
                comment = 1;
            }
        }
        //大队
        //如果comment=null  大队=日常+特勤
        List<Map<String, Object>> merge = signMapper.signInSpecialDetail(sectionId, startTime, endTime, station, comment);
        //人员信息
        for (Map<String, Object> map : merge) {
            //人员
            List<Map> signInAfews = signMapper.SignInStationInfo(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, map.get("class").toString(), Integer.valueOf(map.get("comment").toString()));
            //巡查时长和里程
            for (Map signInAfew : signInAfews) {
                Map map1 = duration(Integer.valueOf(signInAfew.get("staffid").toString()), startTime, endTime);
                signInAfew.put("duration", map1.get("duration"));
                signInAfew.put("mileages", map1.get("mileages"));
            }
            map.put("signInAfew", signInAfews.size());
            map.put("detail", signInAfews);
        }
        return merge;

    }


    @Override
    public String SignInExport(HttpServletResponse response, Integer sectionId, String startTime, String
            endTime, Integer shiftop) throws IOException, ParseException {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //包含的大队
        List<Map> maps = signMapper.signInNumber(sectionId, startTime, endTime, shiftop, null);
        //总合计
        int num = 0;

        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 设置只导出有别名的字段
        writer.setOnlyAlias(true);
        ArrayList<Map<String, Object>> rows = CollUtil.newArrayList();

        for (Map map : maps) {
            Map<String, Object> row1 = new LinkedHashMap<>();
            row1.put("单位", map.get("sectionName"));
            //各大队人员数量
            List<Map> maps1 = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, 1, 1);
            List<Map> maps2 = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, 2, 1);
            List<Map> maps3 = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, 4, 1);
            List<Map> maps4 = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, 3, 1);
            List<Map> maps5 = signMapper.signInAfew(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, 2);

            row1.put("上午班", maps1.size());
            row1.put("下午班", maps2.size());
            row1.put("全天班", maps3.size());
            row1.put("夜巡", maps4.size());
            row1.put("特勤", maps5.size());

            int count = maps1.size() + maps2.size() + maps3.size() + maps4.size() + maps5.size();
            row1.put("合计", count);
            num += count;
            rows.add(row1);

        }
        String time = "日期：" + simpleDateFormat.format(simpleDateFormat.parse(startTime)) + "\n";
        String signNum = "签到数：" + num;
        // 合并单元格后的标题行，使用默认标题样式
        writer.renameSheet("支队统计");
        writer.merge(6, time + signNum);
        writer.write(rows, true);
        writer.setRowHeight(0, 45);
        writer.setColumnWidth(-1, 20);

        for (Map mapm : maps) {
            //包含的中队
            List<Map> mapes = signMapper.signInNumberLeader(Integer.valueOf(mapm.get("sectionpid").toString()), startTime, endTime, shiftop);
            //总合计
            int nums = 0;
            // 设置只导出有别名的字段
            writer.setOnlyAlias(true);
            ArrayList<Map<String, Object>> rowes = CollUtil.newArrayList();
            for (Map map : mapes) {
                Map<String, Object> rowe1 = new LinkedHashMap<>();
                rowe1.put("单位", map.get("sectionName"));
                //各大队人员数量
                List<Map> maps1 = signMapper.signInAfewLeader(Integer.valueOf(map.get("sectionid").toString()), startTime, endTime, 1, 1);
                List<Map> maps2 = signMapper.signInAfewLeader(Integer.valueOf(map.get("sectionid").toString()), startTime, endTime, 2, 1);
                List<Map> maps3 = signMapper.signInAfewLeader(Integer.valueOf(map.get("sectionid").toString()), startTime, endTime, 4, 1);
                List<Map> maps4 = signMapper.signInAfewLeader(Integer.valueOf(map.get("sectionid").toString()), startTime, endTime, 3, 1);
                List<Map> maps5 = signMapper.signInAfewLeader(Integer.valueOf(map.get("sectionid").toString()), startTime, endTime, null, 2);

                rowe1.put("上午班", maps1.size());
                rowe1.put("下午班", maps2.size());
                rowe1.put("全天班", maps3.size());
                rowe1.put("夜巡", maps4.size());
                rowe1.put("特勤", maps5.size());

                int count = maps1.size() + maps2.size() + maps3.size() + maps4.size() + maps5.size();
                rowe1.put("合计", count);
                nums += count;

                rowes.add(rowe1);

            }

            String times = "日期：" + simpleDateFormat.format(simpleDateFormat.parse(startTime)) + "\n";
            String signNums = "签到数：" + nums;
            writer.setSheet(mapm.get("sectionName") + "统计");
            // 合并单元格后的标题行，使用默认标题样式
            writer.merge(6, times + signNums);
            // 一次性写出内容，使用默认样式，强制输出标题
            writer.write(rowes, true);
            writer.setRowHeight(0, 45);
            writer.setColumnWidth(-1, 20);

        }
        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        ServletOutputStream out = response.getOutputStream();
        // 关闭writer，释放内存
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

        return fileName;
    }

    /**
     * 支队层面统计 导出
     *
     * @param sectionId 部门id
     * @param startTime 开始时间
     * @param endTime   结束时间
     */
    public void generalSection(HttpServletResponse response, Integer sectionId, String startTime, String endTime) throws IOException {
        long between1 = DateUtil.between(DateUtil.parseDateTime(startTime), DateUtil.parseDateTime(endTime), DateUnit.DAY);
        long num = between1 + 1;


        SignGeneral signGeneral = new SignGeneral();
        if (StrUtil.isEmpty(startTime) || StrUtil.isEmpty(endTime)) {
            startTime = DataTime.getStartDay();
            endTime = DataTime.getEndDay();
        }

        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        ArrayList<Map<String, Object>> rows = CollUtil.newArrayList();

        //获取大队下的支队
        List<Section> sections = sectionMapper.selectList(Wrappers.<Section>lambdaQuery()
                .eq(Section::getSectionPid, sectionId));
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        for (Section section : sections) {
            Map<String, Object> rowe1 = new LinkedHashMap<>();
            //大队岗位数
            int deptPost = 0;
            //大队签到岗位数
            int deptSignPost = 0;
            double sumMileage = 0;
            int totalTimes = 0;
            //对应接处警和长峰机构代码
            String sectionTel = section.getSectionTel();
            //总签到人数
            int totalForces = signMapper.findTotalForces(section.getSysSectionId(), startTime, endTime, null);
            //路面警力签到数
            int totalForces1 = signMapper.findTotalForces(section.getSysSectionId(), startTime, endTime, 1);
            //路面总警力
            int totalPeople = signMapper.findTotalPolice(section.getSysSectionId(), 1);
            //总警力
            int totalPeoples = signMapper.findTotalPolice(section.getSysSectionId(), null);

            //路面警力签到率（路面警力签到数/路面警力总警力）
            String format;
            if (totalForces1 == 0) {
                format = "0";
            } else {
                format = numberFormat.format(1.0 * totalForces1 / totalPeople * 100);
            }

            String dui = section.getSectionName();
            dui.substring(dui.indexOf('队') + 1);

            //现场执法量
            int xc = illegalDataMapper.selectCount(Wrappers.<IllegalData>lambdaQuery()
                    .like(StringUtils.isNotEmpty(dui), IllegalData::getBattalion, dui)
                    .between(IllegalData::getWfsj, startTime, endTime)
                    .eq(IllegalData::getType, 1));
            //非现场执法量
            int fxc = illegalDataMapper.selectCount(Wrappers.<IllegalData>lambdaQuery()
                    .like(StringUtils.isNotEmpty(dui), IllegalData::getBattalion, dui)
                    .between(IllegalData::getWfsj, startTime, endTime)
                    .eq(IllegalData::getType, 2));
            //接处警数量
            int policeNum = policeDataMapper.selectCount(Wrappers.<PoliceData>lambdaQuery()
                    .like(PoliceData::getJjdw, sectionTel)
                    .between(PoliceData::getJjsj01, startTime, endTime));
            //人均巡查里程（总里程/人数）（公里）
            //大队总里程
            double perCapitaMileage;
            double totalMileage = gpsMapper.totalDistance(section.getSysSectionId(), startTime, endTime);
            if (totalMileage == 0 || totalPeople == 0) {
                perCapitaMileage = 0;
            } else {
                sumMileage += totalMileage;
                DecimalFormat dub = new DecimalFormat("#0.00");
                perCapitaMileage = Double.valueOf(dub.format(totalMileage / 1000 / totalPeople));

            }
            //人均在线时长(支队总时长/总警力)
            int perCapita;
            int totalTime = signMapper.findTotalTime(section.getSysSectionId(), startTime, endTime);
            totalTimes += totalTime;
            if (totalTime == 0 || totalPeople == 0) {
                perCapita = 0;
            } else {
                perCapita = totalTime / totalPeople;

            }

            //主动发现警情数
            int problemNum = problemMapper.problemReportedType(section.getSysSectionId(), startTime, endTime, null);

            //统计各支队岗位数
            Integer count = xareaMapper.selectCount(Wrappers.<Xarea>lambdaQuery().
                    eq(Xarea::getWhether, 1)
                    .eq(Xarea::getSectionDid, section.getSysSectionId()));

            //统计各支队签到岗位数
            Integer signXarea = xareaMapper.findSignXarea(section.getSysSectionId(), startTime, endTime);
            double per = 0.0;
            //签到各岗位率
            if (Objects.nonNull(signXarea)) {
                per = 1.0 * signXarea / count;
                deptPost += count;
                deptSignPost += signXarea;
            }
            //总签到人数
            int totalSign = signMapper.findTotalForces(section.getSysSectionId(), startTime, endTime, null);
            //当日部署警力
            Integer locationPolice = xareaMapper.findLocationPolice(section.getSysSectionId());
            signGeneral.setSectionName(section.getSectionName());
            signGeneral.setSignNum(totalSign);
            signGeneral.setPoliceNum(totalForces1);
            signGeneral.setPoliceRate(format);
            signGeneral.setDuration(perCapita);
            signGeneral.setMileage(perCapitaMileage);
            signGeneral.setSiteIllegal(xc);
            signGeneral.setOffsiteIllegal(fxc);
            signGeneral.setJiechu(policeNum);
            signGeneral.setProblem(problemNum);
            signGeneral.setSignTime(DateUtil.parseDateTime(startTime));
            signGeneral.setCreatTime(new Date());
            signGeneral.setSectionId(section.getSysSectionId());

            signGeneral.setTotalTime(totalTime);
            signGeneral.setTotalDistance(totalMileage);
            signGeneral.setTotalForces(totalPeople);
            signGeneral.setSumForces(totalPeoples);

            signGeneral.setPostNum(count);
            signGeneral.setPostSign(signXarea);
            DecimalFormat df = new DecimalFormat("0.00");
            signGeneral.setPostSignRate(df.format(per));

            signGeneral.setLocationPolice(locationPolice);
            if (Objects.nonNull(locationPolice)) {
                signGeneral.setLocationPoliceRate(df.format(1.0 * totalSign / locationPolice));
            }


            rowe1.put("单位", signGeneral.getSectionName());
            rowe1.put("总警力", signGeneral.getSumForces());
//                rowe1.put("当日部署警力", signGeneral.getLocationPolice());
            rowe1.put("当日总签到人数", signGeneral.getSignNum());
//                rowe1.put("签到率",todaySignRate);

            rowe1.put("路面警力", signGeneral.getTotalForces());
            rowe1.put("当日路面警力签到数", signGeneral.getPoliceNum());
            //路面警力签到率  =路面签到警力/路面总警力
            String signRate;
            if (signGeneral.getPoliceNum() > 0) {
                //signRate = numberFormat.format(((float) signGeneral.getPoliceNum() / signGeneral.getTotalForces()) * 100);
                signRate = numberFormat.format(((float) Double.parseDouble(signGeneral.getPoliceRate()) / num));
            } else {
                signRate = "0";
            }
            rowe1.put("当日路面警力签到率", signRate + "%");

//                rowe1.put("部署岗位总数", signGeneral.getPostNum());
//                rowe1.put("签到岗位数", signGeneral.getPostSign());
//                rowe1.put("岗位签到率", postSignRate);

            rowe1.put("路面人均在线时长（分钟）", perCapita);
            rowe1.put("路面人均巡逻里程（公里）", perCapitaMileage);
            rowe1.put("当日现场执法量", signGeneral.getSiteIllegal());
            rowe1.put("当日非现场执法量", signGeneral.getOffsiteIllegal());
            rowe1.put("当日接处警量", signGeneral.getJiechu());
            rowe1.put("当日主动上报警情量", signGeneral.getProblem());


            rows.add(rowe1);
        }


        String times = "(" + DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + " - " + DateUtil.format(DateUtil.parseDate(endTime), "MM.dd") + ")";
        String tal = "郑州交管局全项勤务数据统计表" + times;
        String comment1 = "计算公式：                           \n" +
                "总警力  =   该单位总人数（含民警、辅警）\n" +
                "当周日均签到人数 =   该单位当周总签到人数/当周天数\n" +
                "路面警力 =   该单位勤务部门总人数（含民警、辅警）\n" +
                "当周路面警力日均签到数 =   该单位当周路面警力签到总人数/当周天数\n" +
                "当周路面警力签到率  =   当周每日路面警力签到率之和/当周天数\n" +
                " 当周路面人均在线时长（巡逻里程）=   该单位当周路面警力总时长（总巡逻里程）/该单位当周路面警力签到总人数\n" +
                " 当周现场（非现场）执法量  =   该单位当周内现场（非现场）执法总数\n" +
                "当周接处警（上报警情）量  =  该单位当周内接处警（上报警情）总数" +
                " 岗位签到率 = 签到岗位数 / 部署岗位总数";
        String comment = "备注：总警力为各支队全部警力数（含民警、辅警），路面警力为各勤务大队所含警力数（含民警、辅警），路面警力签到率为路面警力签到数除以路面警力的比值。办公室、车管、事故、案侦或其他内勤人员仅在执行外勤任务时签到，签到数作为参考，但不计入路面警力签到数。 \n" +
                "     全项勤务统计表采用三色预警机制，综合各支队辖区面积、警力数量、勤务模式进行考量，绿色表示该项数据在全局同序列中较为优异，黄色表示该项数据在全局同序列中有待加强，红色表示该项数据在全局同序列中居于落后位置。";
        // 合并单元格后的标题行，使用默认标题样式
        writer.merge(11, tal);

        writer.merge(rows.size() + 2, rows.size() + 2, 0, 11, comment, false);
        writer.merge(rows.size() + 3, rows.size() + 3, 0, 11, comment1, false);

        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(rows, true);

        writer.setRowHeight(-1, 40);
        writer.setColumnWidth(-1, 9);
        writer.renameSheet(tal);


        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        ServletOutputStream out = response.getOutputStream();
        // 关闭writer，释放内存
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

    }

    /**
     * 各大队数据统计
     */
    @Override
    public void General(String startTime, String endTime) {
        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            startTime = DataTime.getStartDay();
            endTime = DataTime.getEndDay();
        }
        log.info("各大队数据统计{}-{}", startTime, endTime);
        //获取需统计的各支队
        //去掉八支队
        List<Map> maps = sectionMapper.findSectionDids(null);
        log.info("获取各支队信息：：{}", maps);
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        int totalTimes = 0;
        double sumMileage = 0;
        int sumPolices = 0;
        //大队岗位数
        int deptPost = 0;
        //大队签到岗位数
        int deptSignPost = 0;
        //当日部署警力
        int todayLocationSum = 0;
        for (Map map : maps) {
            Integer sectionpid = Integer.valueOf(map.get("sectionpid").toString());
            String section_tel = map.get("section_tel").toString();

            //单位
            String sectionName = map.get("sectionName").toString();
            //总签到人数
            int totalSign = signMapper.findTotalForces(sectionpid, startTime, endTime, null);

            //路面警力签到数（需导出标黄的部门）
            int totalForces1 = signMapper.findTotalForces(sectionpid, startTime, endTime, 1);

            //路面警力总警力
            int totalPeople = signMapper.findTotalPolice(sectionpid, 1);
            //总警力
            int totalPeoples = signMapper.findTotalPolice(sectionpid, null);

            //当日部署警力
            Integer locationPolice = xareaMapper.findLocationPolice(sectionpid);
            todayLocationSum += locationPolice;
            //路面警力签到率（路面警力签到数/路面警力总警力）
            String format;
            if (totalForces1 == 0) {
                format = "0";
            } else {
                format = numberFormat.format(((float) totalForces1 / totalPeople) * 100);
            }

            //一支队一中队：获取第一个队
            String dui = sectionName.substring(0, sectionName.indexOf("队") + 1);
            //dui = dui.replace("支", "大");
            if (!dui.contains("高速")) {
                dui = "交警" + dui;
            }
            if ("高速一支队".equals(dui)) {
                dui = "高速公路交通警察一支队";
            }
            if ("高速二支队".equals(dui)) {
                dui = "高速公路交通警察二支队";
            }
            //现场执法量
            int xc = illegalDataMapper.selectCount(Wrappers.<IllegalData>lambdaQuery()
                    .like(StringUtils.isNotEmpty(dui), IllegalData::getBattalion, dui)
                    .between(IllegalData::getWfsj, startTime, endTime)
                    .eq(IllegalData::getType, 1));
            //非现场执法量
            int fxc = illegalDataMapper.selectCount(Wrappers.<IllegalData>lambdaQuery()
                    .like(StringUtils.isNotEmpty(dui), IllegalData::getBattalion, dui)
                    .between(IllegalData::getWfsj, startTime, endTime)
                    .eq(IllegalData::getType, 2));
            //接处警数量
            int policeNum = policeDataMapper.selectCount(Wrappers.<PoliceData>lambdaQuery()
                    .like(PoliceData::getJjdw, section_tel)
                    .between(PoliceData::getJjsj01, startTime, endTime));


            //人均巡查里程（总里程/人数）（公里）
            //大队总里程
            double perCapitaMileage;
            double totalMileage = gpsMapper.totalDistance(sectionpid, startTime, endTime);
            if (totalMileage == 0 || totalPeople == 0) {
                perCapitaMileage = 0;
            } else {
                sumMileage += totalMileage;
                DecimalFormat dub = new DecimalFormat("#0.00");
                perCapitaMileage = Double.valueOf(dub.format(totalMileage / 1000 / totalPeople));

            }

            //人均在线时长(支队总时长/总警力)
            int perCapita;
            int totalTime = signMapper.findTotalTime(sectionpid, startTime, endTime);
            totalTimes += totalTime;
            if (totalTime == 0 || totalPeople == 0) {
                perCapita = 0;
            } else {
                perCapita = totalTime / totalPeople;

            }

            //主动发现警情数
            int problemNum = problemMapper.problemReportedType(sectionpid, startTime, endTime, null);

            //统计各支队岗位数
            Integer count = xareaMapper.selectCount(Wrappers.<Xarea>lambdaQuery().
                    eq(Xarea::getWhether, 1)
                    .eq(Xarea::getSectionDid, sectionpid));


            //统计各支队签到岗位数
            Integer signXarea = xareaMapper.findSignXarea(sectionpid, startTime, endTime);
            log.info("统计各支队签到岗位数：：{}:::{}", signXarea, sectionpid);
            double per = 0.0;
            //签到各岗位率
            if (Objects.nonNull(signXarea)) {
                per = 1.0 * signXarea / count;
                deptPost += count;
                deptSignPost += signXarea;
            }


            SignGeneral signGeneral = new SignGeneral();
            signGeneral.setSectionName(sectionName);
            signGeneral.setSignNum(totalSign);
            signGeneral.setPoliceNum(totalForces1);
            signGeneral.setPoliceRate(format);
            signGeneral.setDuration(perCapita);
            signGeneral.setMileage(perCapitaMileage);
            signGeneral.setSiteIllegal(xc);
            signGeneral.setOffsiteIllegal(fxc);
            signGeneral.setJiechu(policeNum);
            signGeneral.setProblem(problemNum);
            signGeneral.setSignTime(DateUtil.parseDateTime(startTime));
            signGeneral.setCreatTime(new Date());
            signGeneral.setSectionId(sectionpid);

            signGeneral.setTotalTime(totalTime);
            signGeneral.setTotalDistance(totalMileage);
            signGeneral.setTotalForces(totalPeople);
            signGeneral.setSumForces(totalPeoples);

            signGeneral.setPostNum(count);
            signGeneral.setPostSign(signXarea);
            DecimalFormat df = new DecimalFormat("0.00");
            signGeneral.setPostSignRate(df.format(per));

            signGeneral.setLocationPolice(locationPolice);
            signGeneral.setLocationPoliceRate(df.format(1.0 * totalSign / locationPolice));

            sumPolices += totalPeoples;
            signGeneralMapper.insertIgnoreNull(signGeneral);

        }
        //=======其他===========
        SignGeneral signGenerals = new SignGeneral();
        //总签到数
        int totalSign = signMapper.findTotalForces(null, startTime, endTime, null);
        //各队签到人数
        int signNum = signGeneralMapper.findSignNum(startTime, "支队");

        int nums = totalSign - signNum;
        signGenerals.setSignNum(nums);

        //人均在线时长 (总时长-六个大队时长  / 总签到数)
        int totalTime = signMapper.findTotalTime(null, startTime, endTime);
        int signMileage1 = totalTime - totalTimes;
        if (signMileage1 > 0 && nums != 0) {
            signGenerals.setDuration(signMileage1 / nums);
        } else {
            signGenerals.setDuration(0);
        }

        //人均巡逻里程
        double totalMileage = gpsMapper.totalDistance(null, startTime, endTime);
        double sylic = totalMileage - sumMileage;
        if (sylic > 0 && nums > 0) {
            DecimalFormat dub = new DecimalFormat("#0.00");
            signGenerals.setMileage(Double.valueOf(dub.format(sylic / 1000 / nums)));
        } else {
            signGenerals.setMileage(0);
        }
        //现场执法量
        int xc = illegalDataMapper.selectCount(Wrappers.<IllegalData>lambdaQuery()
                .between(IllegalData::getWfsj, startTime, endTime)
                .eq(IllegalData::getType, 1));
        int signSiteIllegal = signGeneralMapper.findSignSiteIllegal(startTime, "支队");
        signGenerals.setSiteIllegal(xc - signSiteIllegal);


        //非现场执法量
        int fxc = illegalDataMapper.selectCount(Wrappers.<IllegalData>lambdaQuery()
                .between(IllegalData::getWfsj, startTime, endTime)
                .eq(IllegalData::getType, 2));
        int signoffsiteIllegal = signGeneralMapper.findSignoffsiteIllegal(startTime, "支队");
        signGenerals.setOffsiteIllegal(fxc - signoffsiteIllegal);

        //接处警数量
        int policeNum = policeDataMapper.selectCount(Wrappers.<PoliceData>lambdaQuery()
                .between(PoliceData::getJjsj01, startTime, endTime));
        int signJiechu = signGeneralMapper.findSignJiechu(startTime, "支队");
        signGenerals.setJiechu(policeNum - signJiechu);


        //主动上报警情
        int problemNum = problemMapper.problemReportedType(null, startTime, endTime, null);
        int signProblem = signGeneralMapper.findSignProblem(startTime, "支队");
        signGenerals.setProblem(problemNum - signProblem);

        signGenerals.setSectionName("其他");
        signGenerals.setSectionId(0);
        signGenerals.setSignTime(DateUtil.parseDateTime(startTime));
        signGenerals.setCreatTime(new Date());

        signGenerals.setTotalTime(signMileage1);
        signGenerals.setTotalDistance(sylic);
        signGenerals.setTotalForces(0);
        signGenerals.setSumForces(0);
        signGenerals.setPostNum(0);
        signGenerals.setPostSign(0);
        signGenerals.setPostSignRate("0");

        signGenerals.setLocationPolice(0);
        signGenerals.setLocationPoliceRate("0");
        signGeneralMapper.insertIgnoreNull(signGenerals);

        //=======合计===========
        SignGeneral signGeneral2 = new SignGeneral();
        signGeneral2.setSectionName("合计");
        signGeneral2.setSectionId(-1);
        signGeneral2.setSignTime(DateUtil.parseDateTime(startTime));
        signGeneral2.setCreatTime(new Date());

        signGeneral2.setSignNum(totalSign);
        int totalForces = signMapper.findTotalForces(null, startTime, endTime, 1);
        signGeneral2.setPoliceNum(totalForces);
        int totalSigns = signMapper.findTotalForces(null, startTime, endTime, 1);
        int totalPeoples = signMapper.findTotalPolice(null, 1);
        //int sumPeoples = signMapper.findTotalPolice(null, null);
        signGeneral2.setPoliceRate(numberFormat.format(((float) totalSigns / totalPeoples) * 100) + "%");


        if (totalTime > 0 && totalForces != 0) {
            signGeneral2.setDuration(totalTime / totalForces);
        } else {
            signGeneral2.setDuration(0);
        }
        if (totalMileage > 0 && totalForces != 0) {
            DecimalFormat dub = new DecimalFormat("#0.00");
            double hjMileage = Double.valueOf(dub.format(totalMileage / 1000 / totalForces));
            signGeneral2.setMileage(hjMileage);
        } else {
            signGenerals.setMileage(0);
        }

        signGeneral2.setSiteIllegal(xc);
        signGeneral2.setOffsiteIllegal(fxc);
        signGeneral2.setJiechu(policeNum);
        signGeneral2.setProblem(problemNum);

        signGeneral2.setTotalTime(totalTime);
        signGeneral2.setTotalDistance(totalMileage);
        signGeneral2.setTotalForces(totalPeoples);
        signGeneral2.setSumForces(sumPolices);

        signGeneral2.setPostNum(deptPost);
        signGeneral2.setPostSign(deptSignPost);

        double per = 1.0 * deptSignPost / deptPost;
        DecimalFormat df = new DecimalFormat("0.00");
        signGeneral2.setPostSignRate(df.format(per));

        signGeneral2.setLocationPolice(todayLocationSum);

        signGeneral2.setLocationPoliceRate(df.format(1.0 * signGeneral2.getSignNum() / todayLocationSum));
        signGeneralMapper.insertIgnoreNull(signGeneral2);

    }

    /**
     * 按周、月统计导出
     */
    @Override
    public String StatisticsExportByWeek(HttpServletResponse response, Integer sectionId, String startTime, String
            endTime) throws IOException {
        long between1 = DateUtil.between(DateUtil.parseDateTime(startTime), DateUtil.parseDateTime(endTime), DateUnit.DAY);
        long num = between1 + 1;
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(1);
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        ArrayList<Map<String, Object>> rows = CollUtil.newArrayList();

        List<SignGeneral> signGeneralByWeek = signGeneralMapper.findSignGeneralByWeek(sectionId, startTime, endTime);

        for (SignGeneral signGeneral : signGeneralByWeek) {
            //去掉八支队
            if (!signGeneral.getSectionName().equals("八支队")) {
                Map<String, Object> rowe1 = new LinkedHashMap<>();

                //路面警力签到率  =路面签到警力/路面总警力
                String signRate;
                if (signGeneral.getPoliceNum() > 0) {
                    //signRate = numberFormat.format(((float) signGeneral.getPoliceNum() / signGeneral.getTotalForces()) * 100);
                    signRate = numberFormat.format(((float) Double.parseDouble(signGeneral.getPoliceRate()) / num));
                } else {
                    signRate = "0";
                }

                //岗位签到率
                String postSignRate;
                if (signGeneral.getPostSign() > 0 && signGeneral.getPostNum() > 0) {
                    postSignRate = numberFormat.format(((float) signGeneral.getPostSign() / signGeneral.getPostNum()) * 100) + "%";
                } else {
                    postSignRate = "0%";
                }

                //签到率
                String todaySignRate;
                if (signGeneral.getLocationPolice() > 0 && signGeneral.getSignNum() > 0) {
                    todaySignRate = numberFormat.format(((float) signGeneral.getSignNum() / signGeneral.getLocationPolice()) * 100) + "%";
                } else {
                    todaySignRate = "0%";
                }

                //人均时长= 路面警力总时长/路面总警力
                int perCapita;
                if (signGeneral.getTotalTime() > 0 && signGeneral.getSignNum() > 0) {
                    perCapita = signGeneral.getTotalTime() / signGeneral.getSignNum();
                } else {
                    perCapita = 0;
                }
                //人均里程 = 路面警力总巡查里程/路面总警力
                double perCapitaMileage;
                if (signGeneral.getTotalTime() > 0 && signGeneral.getSignNum() > 0) {
                    perCapitaMileage = signGeneral.getTotalDistance() / 1000 / signGeneral.getSignNum();
                } else {
                    perCapitaMileage = 0;
                }

                if (between1 < 4) {
                    rowe1.put("单位", signGeneral.getSectionName());
                    rowe1.put("总警力", signGeneral.getSumForces());
//                rowe1.put("当日部署警力", signGeneral.getLocationPolice());
                    rowe1.put("当日总签到人数", signGeneral.getSignNum());
//                rowe1.put("签到率",todaySignRate);

                    rowe1.put("路面警力", signGeneral.getTotalForces());
                    rowe1.put("当日路面警力签到数", signGeneral.getPoliceNum());
                    rowe1.put("当日路面警力签到率", signRate + "%");

//                rowe1.put("部署岗位总数", signGeneral.getPostNum());
//                rowe1.put("签到岗位数", signGeneral.getPostSign());
//                rowe1.put("岗位签到率", postSignRate);

                    rowe1.put("路面人均在线时长（分钟）", perCapita);
                    rowe1.put("路面人均巡逻里程（公里）", perCapitaMileage);
                    rowe1.put("当日现场执法量", signGeneral.getSiteIllegal());
                    rowe1.put("当日非现场执法量", signGeneral.getOffsiteIllegal());
                    rowe1.put("当日接处警量", signGeneral.getJiechu());
                    rowe1.put("当日主动上报警情量", signGeneral.getProblem());


                    rows.add(rowe1);
                } else if (4 < between1 && between1 <= 8) {

                    rowe1.put("单位", signGeneral.getSectionName());
                    if (signGeneral.getSectionId() == 0) {
                        rowe1.put("总警力", "/");
//                    rowe1.put("当日部署警力",  "/");
                    } else {
                        rowe1.put("总警力", signGeneral.getSumForces());
//                    rowe1.put("当日部署警力", signGeneral.getLocationPolice());
                    }

                    rowe1.put("一周日均签到人数", numberFormat.format(((float) signGeneral.getSignNum() / 7)));
                    if (signGeneral.getSectionId() == 0) {
//                    rowe1.put("签到率","/");
                        rowe1.put("路面警力", "/");
                        rowe1.put("一周路面警力日均签到数", "/");
                        rowe1.put("一周路面警力签到率", "/");
                        rowe1.put("路面人均在线时长（分钟）", "/");
                        rowe1.put("路面人均巡逻里程（公里）", "/");
                        rowe1.put("一周日均部署岗位总数", "/");
                        rowe1.put("一周日均签到岗位数", "/");
                        rowe1.put("岗位签到率", "/");
                    } else {
//                    rowe1.put("签到率",todaySignRate);
                        rowe1.put("路面警力", signGeneral.getTotalForces());
                        rowe1.put("一周路面警力日均签到数", numberFormat.format(((float) signGeneral.getPoliceNum() / 7)));
                        rowe1.put("一周路面警力签到率", signRate + "%");
                        rowe1.put("路面人均在线时长（分钟）", perCapita);
                        rowe1.put("路面人均巡逻里程（公里）", perCapitaMileage);
//                    rowe1.put("一周日均部署岗位总数", numberFormat.format(((float) signGeneral.getPostNum() / 7)));
//                    rowe1.put("一周日均签到岗位数", numberFormat.format(((float) signGeneral.getPostSign() / 7)));
//                    rowe1.put("岗位签到率", postSignRate);
                    }


                    rowe1.put("一周现场执法量", signGeneral.getSiteIllegal());
                    rowe1.put("一周非现场执法量", signGeneral.getOffsiteIllegal());
                    rowe1.put("一周接处警量", signGeneral.getJiechu());
                    rowe1.put("一周主动上报警情量", signGeneral.getProblem());


                    rows.add(rowe1);
                } else {

                    rowe1.put("单位", signGeneral.getSectionName());
                    if (signGeneral.getSectionId() == 0) {
                        rowe1.put("总警力", "/");
                    } else {
                        rowe1.put("总警力", signGeneral.getSumForces());
                    }

                    rowe1.put("当月日均签到人数", numberFormat.format(((float) signGeneral.getSignNum() / num)));
                    //其他
                    if (signGeneral.getSectionId() == 0) {
//                    rowe1.put("签到率","/");
                        rowe1.put("路面警力", "/");
                        rowe1.put("当月路面警力日均签到数", "/");
                        rowe1.put("路面警力签到率", "/");
                        rowe1.put("路面人均在线时长（分钟）", "/");
                        rowe1.put("路面人均巡逻里程（公里）", "/");
                        rowe1.put("一周日均部署岗位总数", "/");
                        rowe1.put("一周日均签到岗位数", "/");
                        rowe1.put("岗位签到率", "/");
                    } else {
//                    rowe1.put("签到率",todaySignRate);
                        rowe1.put("路面警力", signGeneral.getTotalForces());
                        rowe1.put("当月路面警力日均签到数", numberFormat.format(((float) signGeneral.getPoliceNum() / num)));
                        rowe1.put("路面警力签到率", signRate + "%");

                        rowe1.put("一周日均部署岗位总数", numberFormat.format(((float) signGeneral.getPostNum() / num)));
                        rowe1.put("一周日均签到岗位数", numberFormat.format(((float) signGeneral.getPostSign() / num)));
                        rowe1.put("岗位签到率", postSignRate);

                        rowe1.put("路面人均在线时长（分钟）", perCapita);
                        rowe1.put("路面人均巡逻里程（公里）", perCapitaMileage);
                    }

                    rowe1.put("当月现场执法量", signGeneral.getSiteIllegal());
                    rowe1.put("当月非现场执法量", signGeneral.getOffsiteIllegal());
                    rowe1.put("当月接处警量", signGeneral.getJiechu());
                    rowe1.put("当月主动上报警情量", signGeneral.getProblem());


                    rows.add(rowe1);
                }

            }
        }


        String times;
        String tal;
        String comment1 = null;
        if (between1 < 4) {
            times = "(" + DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + ")";
            tal = "郑州交管局每日全项勤务数据统计表" + times;
        } else if (4 < between1 && between1 <= 8) {
            times = "(" + DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + " - " + DateUtil.format(DateUtil.parseDate(endTime), "MM.dd") + ")";
            tal = "郑州交管局全项勤务数据统计表" + times;
            comment1 = "计算公式：                           \n" +
                    "总警力  =   该单位总人数（含民警、辅警）\n" +
                    "当周日均签到人数 =   该单位当周总签到人数/当周天数\n" +
                    "路面警力 =   该单位勤务部门总人数（含民警、辅警）\n" +
                    "当周路面警力日均签到数 =   该单位当周路面警力签到总人数/当周天数\n" +
                    "当周路面警力签到率  =   当周每日路面警力签到率之和/当周天数\n" +
                    " 当周路面人均在线时长（巡逻里程）=   该单位当周路面警力总时长（总巡逻里程）/该单位当周路面警力签到总人数\n" +
                    " 当周现场（非现场）执法量  =   该单位当周内现场（非现场）执法总数\n" +
                    "当周接处警（上报警情）量  =  该单位当周内接处警（上报警情）总数" +
                    " 岗位签到率 = 签到岗位数 / 部署岗位总数";
        } else {
            times = "(" + DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + " - " + DateUtil.format(DateUtil.parseDate(endTime), "MM.dd") + ")";
            tal = "郑州交管局全项勤务数据统计表" + times;
            comment1 = "计算公式：                           \n" +
                    "总警力  =   该单位总人数（含民警、辅警）\n" +
                    "当月日均签到人数 =   该单位当月总签到人数/当月天数\n" +
                    "路面警力 =   该单位勤务部门总人数（含民警、辅警）\n" +
                    "当月路面警力日均签到数 =   该单位当月路面警力签到总人数/当月天数\n" +
                    "当月路面警力签到率  =   当月每日路面警力签到率之和/当月天数\n" +
                    " 当月路面人均在线时长（巡逻里程）=   该单位当月路面警力总时长（总巡逻里程）/该单位当月路面警力签到总人数\n" +
                    " 当月现场（非现场）执法量  =   该单位当月内现场（非现场）执法总数\n" +
                    "当月接处警（上报警情）量  =  该单位当月内接处警（上报警情）总数" +
                    " 岗位签到率 = 签到岗位数 / 部署岗位总数";
        }


        String comment = "备注：总警力为各支队全部警力数（含民警、辅警），路面警力为各勤务大队所含警力数（含民警、辅警），路面警力签到率为路面警力签到数除以路面警力的比值。办公室、车管、事故、案侦或其他内勤人员仅在执行外勤任务时签到，签到数作为参考，但不计入路面警力签到数。 \n" +
                "     全项勤务统计表采用三色预警机制，综合各支队辖区面积、警力数量、勤务模式进行考量，绿色表示该项数据在全局同序列中较为优异，黄色表示该项数据在全局同序列中有待加强，红色表示该项数据在全局同序列中居于落后位置。";


        // 合并单元格后的标题行，使用默认标题样式
        writer.merge(11, tal);

        writer.merge(rows.size() + 2, rows.size() + 2, 0, 11, comment, false);
        writer.merge(rows.size() + 3, rows.size() + 3, 0, 11, comment1, false);

        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(rows, true);

        writer.setRowHeight(-1, 40);
        writer.setColumnWidth(-1, 9);
        writer.renameSheet(tal);


        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        ServletOutputStream out = response.getOutputStream();
        // 关闭writer，释放内存
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

        return fileName;


    }

    public List<SignStatistics> mileages(ExcelDto excelDto, Integer depthNumber) {
        depthNumber++;
        //todo 里程前100
        PageHelper.startPage(1, 100);
        List<SignStatistics> signStatistics = signStatisticsMapper.mileages(excelDto);
//        List<SignStatistics> signStatistics = signStatisticsMapper.selectList(Wrappers.<SignStatistics>lambdaQuery()
//                .between(SignStatistics::getSignTime, excelDto.getStartTime(), excelDto.getEndTime())
//                .orderByDesc(SignStatistics::getMileage));
        PageInfo<SignStatistics> pageInfo = new PageInfo<>(signStatistics);
        List<SignStatistics> list = pageInfo.getList();
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setId(i + 1);
        }
        if (depthNumber <= maxDepth) {
            if (list == null || list.size() < 10) {
                String start = DateUtil.offsetDay(DateUtil.parse(excelDto.getStartTime()), -1).toString();
                String end = DateUtil.offsetDay(DateUtil.parse(excelDto.getEndTime()), -1).toString();
                excelDto.setStartTime(start);
                excelDto.setEndTime(end);
                return mileages(excelDto, depthNumber);
            }
        }
        return list;
    }

    public List<SignStatistics> duration(ExcelDto excelDto, Integer depthNumber) {
        depthNumber++;
        //todo 时长前100
        PageHelper.startPage(1, 100);
        List<SignStatistics> times = signMapper.findTime(excelDto);
        PageInfo<SignStatistics> pageInfo = new PageInfo<>(times);
        List<SignStatistics> list = pageInfo.getList();
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setId(i + 1);
        }
        if (depthNumber <= maxDepth) {
            if (list == null || list.size() < 10) {
                String start = DateUtil.offsetDay(DateUtil.parse(excelDto.getStartTime()), -1).toString();
                String end = DateUtil.offsetDay(DateUtil.parse(excelDto.getEndTime()), -1).toString();
                excelDto.setStartTime(start);
                excelDto.setEndTime(end);
                return duration(excelDto, depthNumber);
            }
        }
        return list;
    }

    public List<SignStatistics> jiechuNum(ExcelDto excelDto, Integer depthNumber) {
        depthNumber++;
        //执法量前100
        PageHelper.startPage(1, 100);
        List<SignStatistics> signStatistics = signStatisticsMapper.jiechuNum(excelDto);
//        List<SignStatistics> signStatistics = signStatisticsMapper.selectList(Wrappers.<SignStatistics>lambdaQuery()
//                .between(SignStatistics::getSignTime, excelDto.getStartTime(), excelDto.getEndTime())
//                .orderByDesc(SignStatistics::getIllegalNum));
        PageInfo<SignStatistics> pageInfo = new PageInfo<>(signStatistics);
        List<SignStatistics> list = pageInfo.getList();
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setId(i + 1);
        }
        if (depthNumber <= maxDepth) {
            if (list == null || list.size() < 10) {
                String start = DateUtil.offsetDay(DateUtil.parse(excelDto.getStartTime()), -1).toString();
                String end = DateUtil.offsetDay(DateUtil.parse(excelDto.getEndTime()), -1).toString();
                excelDto.setStartTime(start);
                excelDto.setEndTime(end);
                return jiechuNum(excelDto, depthNumber);
            }
        }
        return list;
    }

    private Integer getSectionId(HttpServletRequest request) {
        String token = request.getHeader(jwtUtils.getHeader());

        String userName = jwtUtils.getClaimByToken(token).getSubject();
        Staff staff = staffMapper.selectOne(Wrappers.<Staff>lambdaQuery().eq(Staff::getStaffTel, userName));
        Integer sectionDid = null;
        if (Objects.nonNull(staff)) {
            sectionDid = staff.getSysSectionId();
            if (staff.getSysSectionId() == 74) {
                sectionDid = null;
            }
        }
        return sectionDid;
    }

    private DutySchedule getDutySchedule() {
        DutySchedule one = new DutySchedule();

        List<DutySchedule> dutySchedules = dutyScheduleMapper.selectList(Wrappers.<DutySchedule>lambdaQuery());
        for (DutySchedule dutySchedule : dutySchedules) {
            String startTime = dutySchedule.getStartTime();
            String endTime = dutySchedule.getEndTime();

            DateTime timeStart = DateUtil.parse(startTime);
            DateTime timeEnd = DateUtil.parse(endTime);

            String time = DateUtil.now().substring(11, 19);
            if (dutySchedule.getSignOutEndMorrow() == 1 && time.compareTo("12:00:00") > 0) {
                timeEnd = DateUtil.offsetDay(timeEnd, 1);
            }
            if (dutySchedule.getSignOutEndMorrow() == 1 && time.compareTo("12:00:00") < 0) {
                timeStart = DateUtil.offsetDay(timeStart, -1);
            }

            Calendar cal = Calendar.getInstance();
            int month = cal.get(Calendar.MONTH) + 1;
            if (month == 5 || month == 6 || month == 7 || month == 8 || month == 9) {
                if (dutySchedule.getSeason() != 1 && dutySchedule.getSeason() != 0) {
                    continue;
                }
            } else { //冬季出勤
                //冬季勤务模式
                if (dutySchedule.getSeason() != 2 && dutySchedule.getSeason() != 0) {
                    continue;
                }
            }
            if (DateUtil.isIn(DateUtil.date(), timeStart, timeEnd)) {
                one = dutySchedule;
                break;
            }

        }
        return one;
    }


    @Override
    public ResultBean order(HttpServletRequest request) {
        String[] signCommentArray = {"早高峰", "晚高峰", "夜班"};
        List<String> strings = Arrays.asList(signCommentArray);
        // 不同角色查看不同内容
        Integer sectionDid = getSectionId(request);

        String startTime1 = DateUtil.today() + " 00:00:00";
        String endTime1 = DateUtil.today() + " 23:59:59";
        String yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday()).toString();
        String yesterdayEnd = DateUtil.endOfDay(DateUtil.yesterday()).toString();
        StatisticsVo todayPolice = signMapper.todayPolice(startTime1, endTime1, sectionDid); //今天的累计在线数量
        int yesterdayPolice = signMapper.yesterdayPolice(yesterdayStart, yesterdayEnd, sectionDid);
        todayPolice.setTotalNum(todayPolice.getTotalNum() + yesterdayPolice);

        String equipageNumber = signMapper.todayEquipageNumber(startTime1, endTime1, sectionDid);

        StatisticsVo currentPolice = signMapper.currentPolice(sectionDid);
        //应签岗位数  当前时间判定高峰岗还是平峰岗还是夜巡
        String today = DateUtil.today();

        DutySchedule one = getDutySchedule();
        //查询签到岗位数,已签岗位数
        //StatisticsVo order1 = xareaMapper.order(sectionDid, one.getModeCode(), today);
        StatisticsVo order = new StatisticsVo();// = signMapper.order(sectionDid, today);
        //StatisticsVo orderAll= xareaMapper.orderAll(sectionDid, one.getModeCode());
        //查询应签岗位数
        StatisticsVo orderAll = new StatisticsVo();
        // 该模式下岗位有多少警力
        Integer modePolice;   //应签警力

        //应签警力，目前写死
        //根据不同角色id查询支队名称
        String staffName = staffMapper.findBySysStaffId(sectionDid);
        if (sectionDid != null) {
            if (staffName.equals("一支队指挥中心")) {
                if (one.getModeCode() == 1) {
                    modePolice = 79;
                } else if (one.getModeCode() == 4) {
                    modePolice = 8;
                } else {
                    modePolice = 64;
                }
            } else if (staffName.equals("二支队指挥中心")) {
                if (one.getModeCode() == 1) {
                    modePolice = 89;
                } else if (one.getModeCode() == 4) {
                    modePolice = 13;
                } else {
                    modePolice = 77;
                }
            } else if (staffName.equals("三支队指挥中心")) {
                if (one.getModeCode() == 1) {
                    modePolice = 80;
                } else if (one.getModeCode() == 4) {
                    modePolice = 8;
                } else {
                    modePolice = 66;
                }
            } else if (staffName.contains("四支队")) {
                if (one.getModeCode() == 1) {
                    modePolice = 48;
                } else if (one.getModeCode() == 4) {
                    modePolice = 12;
                } else {
                    modePolice = 28;
                }
            } else if (staffName.contains("五支队")) {
                if (one.getModeCode() == 1) {
                    modePolice = 101;
                } else if (one.getModeCode() == 4) {
                    modePolice = 19;
                } else {
                    modePolice = 84;
                }
            } else if (staffName.contains("六支队")) {
                if (one.getModeCode() == 1) {
                    modePolice = 154;
                } else if (one.getModeCode() == 4) {
                    modePolice = 48;
                } else {
                    modePolice = 130;
                }
            } else if (staffName.contains("七支队")) {
                if (one.getModeCode() == 1) {
                    modePolice = 6;
                } else if (one.getModeCode() == 4) {
                    modePolice = 0;
                } else {
                    modePolice = 6;
                }
            } else if (staffName.contains("九支队")) {
                if (one.getModeCode() == 1) {
                    modePolice = 22;
                } else if (one.getModeCode() == 4) {
                    modePolice = 0;
                } else {
                    modePolice = 13;
                }
            } else if (staffName.equals("十一支队指挥中心")) {
                if (one.getModeCode() == 1) {
                    modePolice = 16;
                } else if (one.getModeCode() == 4) {
                    modePolice = 2;
                } else {
                    modePolice = 12;
                }
            } else if (staffName.equals("十二支队指挥中心")) {
                if (one.getModeCode() == 1) {
                    modePolice = 19;
                } else if (one.getModeCode() == 4) {
                    modePolice = 12;
                } else {
                    modePolice = 12;
                }
            } else if (staffName.equals("十三支队指挥中心")) {
                if (one.getModeCode() == 1) {
                    modePolice = 0;
                } else if (one.getModeCode() == 4) {
                    modePolice = 10;
                } else {
                    modePolice = 0;
                }
            } else if (staffName.contains("高速一支队")) {
                if (one.getModeCode() == 1) {
                    modePolice = 16;
                } else if (one.getModeCode() == 4) {
                    modePolice = 0;
                } else {
                    modePolice = 16;
                }
            } else if (staffName.contains("高速二支队")) {
                if (one.getModeCode() == 1) {
                    modePolice = 17;
                } else if (one.getModeCode() == 4) {
                    modePolice = 0;
                } else {
                    modePolice = 17;
                }
            } else {
                if (one.getModeCode() == 1) {
                    modePolice = 647;
                } else if (one.getModeCode() == 4) {
                    modePolice = 132;
                } else {
                    modePolice = 525;
                }
            }
        } else {
            if (one.getModeCode() == 1) {
                modePolice = 647;
            } else if (one.getModeCode() == 4) {
                modePolice = 132;
            } else {
                modePolice = 525;
            }
        }
        int[] postCode = new int[6];
        //高峰
        if (one.getModeCode() == 1) {
            postCode[0] = 1;
            postCode[1] = 2;
            postCode[2] = 3;
            postCode[3] = 5;
            postCode[4] = 6;
            postCode[5] = 7;
            //早高峰晚高峰，应签警力数量=高峰+平峰
            //modePolice = xareaMapper.findPolice(sectionDid, mode);
            //高峰，应签岗位=高峰+平峰
            orderAll = xareaMapper.orderAll(sectionDid, postCode);

            //该高峰下的已签岗位
            order = signMapper.order1(sectionDid, today, postCode);
            //夜巡
        } else if (one.getModeCode() == 4) {
            postCode[0] = 4;
            postCode[1] = 7;
            postCode[2] = 8;
            //modePolice = xareaMapper.findPolice(sectionDid, mode);
            //orderAll = xareaMapper.orderAll(sectionDid, postCode);
            List<Integer> numList = xareaMapper.orderAll1(sectionDid, postCode);
            Integer sum = numList.stream().mapToInt(Integer::valueOf).sum();
            orderAll.setShouldPostNum(sum);

            //夜巡下的已签岗位
            List<Map<String, Object>> orderList = signMapper.order2(sectionDid, today, postCode);
            String time = DateUtil.now().substring(11, 19);
            //如果当前时间在12点之前，今天的夜巡数量要加上昨天的夜巡数量
            if (time.compareTo("12:00:00") < 0) {
                //昨天的日期
                String yesTime = DataTime.getStartDay().substring(0, 11);
                List<Map<String, Object>> list = signMapper.order2(sectionDid, yesTime, postCode);
                order.setSignPostNum(list.size());
            } else {
                order.setSignPostNum(orderList.size());
            }
        } else {
            //平峰
            postCode[0] = 2;
            postCode[1] = 3;
            postCode[2] = 5;
            postCode[3] = 6;
            postCode[4] = 7;
            //应签岗位数 shouldPostNum
            orderAll = xareaMapper.orderAll(sectionDid, postCode);

            //平峰下的已签岗位 signPostNum
            order = signMapper.order1(sectionDid, today, postCode);
        }

        if (Objects.nonNull(modePolice) && modePolice != 0 && Objects.nonNull(currentPolice) && Objects.nonNull(currentPolice.getNum())) {
            //签到率=实时在线/应签警力*100.0
            double per = 100.0 * currentPolice.getNum() / modePolice;
            if (per > 100) {
                per = 100;
            }
            BigDecimal bd = new BigDecimal(per);
            bd = bd.setScale(0, RoundingMode.HALF_UP);
            //签到率
            orderAll.setNumPer(bd.toString());
        } else {
            orderAll.setNumPer("0");
        }
        //  end
        orderAll.setSignPostNum(order.getSignPostNum());
        orderAll.setEquipageNumber(equipageNumber);
        //实时在线
        orderAll.setNum(currentPolice.getNum());
        //累计签到
        orderAll.setTotalNum(todayPolice.getTotalNum());
        //查看类型 和时间段
        orderAll.setType(one.getSignComment());
        orderAll.setTime(one.getStartTime() + "-" + one.getEndTime());
        orderAll.setModePolice(modePolice);
        //空岗数量=应签岗位-签到岗位
        orderAll.setSignEmptyNum(orderAll.getShouldPostNum() - orderAll.getSignPostNum());
        double per = 0.0;
        if (Objects.nonNull(orderAll) && Objects.nonNull(orderAll.getShouldPostNum()) && Objects.nonNull(orderAll.getSignPostNum()) && orderAll.getShouldPostNum() != 0) {
            // 岗位签到率=签到岗位数/应签岗位数*100.0
            per = 100.0 * orderAll.getSignPostNum() / orderAll.getShouldPostNum();
        }

        BigDecimal bd = new BigDecimal(per);
        //四舍五入
        bd = bd.setScale(0, RoundingMode.HALF_UP);

        //岗位签到率
        orderAll.setSignPostPer(bd.toString());
        if (!strings.contains(orderAll.getType())) {
            //判断时间是什么时间段
            Calendar cal = Calendar.getInstance();
            int month = cal.get(Calendar.MONTH) + 1;
            List<Gatecard> gatecardByShifop = new ArrayList<>();
            //夏季
            if (month == 5 || month == 6 || month == 7 || month == 8 || month == 9) {
                gatecardByShifop = gatecardMapper.findGatecardByShifop(1, null, 2);
            } else { //冬季出勤
                //冬季勤务模式
                gatecardByShifop = gatecardMapper.findGatecardByShifop(2, null, 2);
            }
            for (Gatecard gatecard : gatecardByShifop) {
                if ("平峰期".equals(gatecard.getName())) {
                    orderAll.setTime(gatecard.getStartTime() + "-" + gatecard.getEndTime());
                }
            }
            orderAll.setType("平峰期");

        }
        return ResultUtil.setOK("查询成功", orderAll);
    }


    @Override
    public ResultBean special() {
        String startTime = DateUtil.today() + " 00:00:00";
        String endTime = DateUtil.today() + " 23:59:59";
        StatisticsVo statisticsVo = signMapper.specialCurrentPolice(startTime, endTime);

        StatisticsVo statisticsVos = signMapper.specialTodayPolice(startTime, endTime);
        statisticsVos.setNum(statisticsVo.getNum());

        return ResultUtil.setOK("查询成功", statisticsVos);
    }

    @Override
    public ResultBean empty(HttpServletRequest request) {
        String today = DateUtil.today();
        //获取当前用户sectionId
        Integer sectionDid = getSectionId(request);
        //获取岗位日程
        DutySchedule one = getDutySchedule();
        //List<Xarea> data = xareaMapper.empty(sectionId, one.getModeCode(), today);
        int[] postCode = new int[6];
        List<Xarea> data = new ArrayList<>();
        //高峰
        if (one.getModeCode() == 1) {
            postCode[0] = 1;
            postCode[1] = 2;
            postCode[2] = 3;
            postCode[3] = 5;
            postCode[4] = 6;
            postCode[5] = 7;
            //该高峰下的空岗
            data = xareaMapper.empty1(sectionDid, today, postCode);
            //夜巡
        } else if (one.getModeCode() == 4) {
            postCode[0] = 4;
            postCode[1] = 7;
            postCode[2] = 8;

            //夜巡下的空岗
            data = xareaMapper.empty1(sectionDid, today, postCode);
        } else {
            //平峰
            postCode[0] = 2;
            postCode[1] = 3;
            postCode[2] = 5;
            postCode[3] = 6;
            postCode[4] = 7;

            //平峰下的空岗
            data = xareaMapper.empty1(sectionDid, today, postCode);
        }
        return ResultUtil.setOK("查询成功", data);
    }


    public void exportTop(HttpServletResponse response, ExcelDto excelDto) {

        //里程前100
        List<SignStatistics> mileages = mileages(excelDto, 31);
        String s1 = JSONUtil.toJsonStr(mileages);
        List<ExcelVoMileage> mileagesVos = JSONUtil.parseArray(s1).toList(ExcelVoMileage.class);
        // 时长前100
        List<SignStatistics> duration = duration(excelDto, 31);
        String s2 = JSONUtil.toJsonStr(duration);
        List<ExcelVoDuration> durationVos = JSONUtil.parseArray(s2).toList(ExcelVoDuration.class);
        // 执法量前100
        List<SignStatistics> jiechuNums = jiechuNum(excelDto, 31);
        String s3 = JSONUtil.toJsonStr(jiechuNums);
        List<ExcelVo> jiechuNumsVos = JSONUtil.parseArray(s3).toList(ExcelVo.class);

        ExcelWriter writer = ExcelUtil.getWriter();
        writer.addHeaderAlias("id", "序号");
        writer.addHeaderAlias("sectionName", "单位名称");
        writer.addHeaderAlias("name", "姓名");
        writer.addHeaderAlias("warningSignal", "警号");
        writer.addHeaderAlias("duration", "在线时长(单位:分钟)");
        writer.addHeaderAlias("illegalNum", "执法量");
        writer.addHeaderAlias("mileage", "巡逻里程");
        //导出里程前100
        ExcelWriter excelWriter = writer.setSheet(0).renameSheet("里程前100");
        excelWriter.write(mileagesVos);
        //时长前100
        ExcelWriter excelWriterTime = writer.setSheet(1).renameSheet("时长前100");
        excelWriterTime.write(durationVos);
        // 执法量前100
        ExcelWriter excelWriterJiechuNums = writer.setSheet(2).renameSheet("执法量前100");
        excelWriterJiechuNums.write(jiechuNumsVos);

        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=out.xls");
            ServletOutputStream out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (Exception e) {
            log.error("导出excel异常", e);
        }
    }

    @Override
    public void exportCount(HttpServletResponse response) {

        String title = "交警勤务岗位统计表";
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);

        writer.setSheet(0).renameSheet("交警勤务岗位统计表");
        List<Map<String, Object>> data = xareaMapper.selectExportCount();
        List<String> battalionList = data.stream().map(x -> x.get("battalion").toString()).collect(Collectors.toList());
        //获取需统计的各支队
        List<String> posts = data.stream().map(x -> x.get("station").toString()).distinct().collect(Collectors.toList());

        Map<Object, List<Map<String, Object>>> station = data.stream().filter(x -> battalionList.contains(x.get("battalion"))).collect(Collectors.groupingBy(x -> x.get("station")));

        writer.merge(0, 0, 0, posts.size() * 2 + 3, title, true);
        //设置标题行属性
        writer.setRowHeight(0, 40);

        writer.writeCellValue(1, 1, "总岗位");
        writer.merge(1, 1, 2, 3, "每日部署警力", false);

        ArrayList<String> strings = CollUtil.newArrayList("", "", "", "");
        for (int i = 0; i < station.keySet().size(); i++) {
            strings.add("岗位");
            strings.add("每班次警力");
        }

        for (int i = 0; i < strings.size(); i++) {
            writer.writeCellValue(i, 2, strings.get(i));
        }
        List<String> xx = new ArrayList<>(10);
        List<String> y = new ArrayList<>(10);

        AtomicInteger j = new AtomicInteger(4);
        //总计总岗位
        AtomicInteger sumPost = new AtomicInteger();
        //总计每日部署警力
        AtomicInteger sumPeople = new AtomicInteger();

        AtomicInteger sumIndex = new AtomicInteger(3);
        Map<Object, List<Map<String, Object>>> battalion = data.stream().filter(x -> Objects.nonNull(x.get("battalion"))).collect(Collectors.groupingBy(x -> x.get("battalion")));

        Map<Object, List<Map<String, Object>>> battalionMap = new LinkedHashMap<>();

        for (String s : battalionList) {
            battalionMap.put(s, battalion.get(s));
        }

        battalionMap.forEach((k, v) -> {
            int postSum = v.stream().mapToInt(x -> Integer.valueOf(String.valueOf(x.get("post")))).sum();
            int peopleSum = v.stream().filter(x -> Objects.nonNull(x.get("people"))).mapToInt(x -> Integer.valueOf(String.valueOf(x.get("people")))).sum();
            sumPost.addAndGet(postSum);
            sumPeople.addAndGet(peopleSum);

            writer.writeCellValue(1, sumIndex.get(), postSum);
            writer.merge(sumIndex.get(), sumIndex.get(), 2, 3, peopleSum, false);
            writer.writeCellValue(0, sumIndex.get(), k);

            sumIndex.getAndIncrement();

            y.add(String.valueOf(k));
        });
        Map<Object, List<Map<String, Object>>> sortPosts = new LinkedHashMap<>();

        for (String s : posts) {
            sortPosts.put(s, station.get(s));
        }
        sortPosts.forEach((kk, vv) -> {
            if (Objects.isNull(vv)) {
                return;
            }
            writer.merge(1, 1, j.get(), j.get() + 1, kk, false);
            //总计 固定岗，高峰岗 。。。
            int peopleSum = vv.stream().mapToInt(x -> Integer.valueOf(x.getOrDefault("people", 0).toString())).sum();
            int postSum = vv.stream().mapToInt(x -> Integer.valueOf(x.getOrDefault("post", 0).toString())).sum();

            writer.writeCellValue(j.get(), y.size() + 3, postSum);
            writer.writeCellValue(j.get() + 1, y.size() + 3, peopleSum);

            j.addAndGet(2);
            xx.add(String.valueOf(kk));
        });

        for (Map<String, Object> map : data) {
            int indexX = xx.indexOf(String.valueOf(map.get("station")));
            int indexY = y.indexOf(String.valueOf(map.get("battalion")));
            if (indexX == -1 || indexY == -1) {
                continue;
            }
            writer.writeCellValue(2 * indexX + 4, indexY + 3, map.get("post"));
            writer.writeCellValue(2 * indexX + 5, indexY + 3, String.valueOf(map.get("people")));
        }

        writer.writeCellValue(0, y.size() + 3, "总计");
        writer.writeCellValue(1, y.size() + 3, sumPost.get());
        writer.merge(y.size() + 3, y.size() + 3, 2, 3, sumPeople.get(), false);
        //设置标题行属性
        writer.setRowHeight(1, 40);

        //设置边框属性
        for (int i = 0; i < xx.size() + 13; i++) {
            for (int yy = 0; yy < y.size() + 4; yy++) {
                CellStyle cellStyle = writer.createCellStyle(i, yy);
                cellStyle.setBorderBottom(BorderStyle.THIN);
                cellStyle.setBorderLeft(BorderStyle.THIN);
                cellStyle.setBorderRight(BorderStyle.THIN);
                cellStyle.setBorderTop(BorderStyle.THIN);
                cellStyle.setAlignment(HorizontalAlignment.LEFT);
                if (yy == 1 || yy == 0) {
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                }
            }
        }

        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=out.xls");
            ServletOutputStream out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (Exception e) {
            log.error("读取excel异常", e);
        }

    }

    @Resource
    DutyPostMapper dutyPostMapper;


    @Override
    public void exportPostCount(HttpServletResponse response) {
        List<DutyPost> dutyPosts = dutyPostMapper.selectList(Wrappers.<DutyPost>lambdaQuery());
        List<Section> sections = xareaMapper.selectSectionList();

        List<Map<String, Object>> postInfo = xareaMapper.selectExportPostCount();
        Map<String, List<Map<String, Object>>> postGroupBySection = postInfo.stream().collect(Collectors.groupingBy(score -> score.get("section_name").toString()));
        Map<String, List<Map<String, Object>>> postGroupBySectionAndPost = postInfo.stream().collect(Collectors.groupingBy(score -> score.get("section_name") + "-" + score.get("post_name")));
        Map<String, Integer> postGroupBySectionCount = postInfo.stream().collect(Collectors.groupingBy(score -> score.get("section_name").toString(),
                Collectors.summingInt(score -> Integer.parseInt(score.get("police").toString()) + Integer.parseInt(score.get("auxiliary").toString()))));
        Map<String, Integer> postGroupBySectionAndPostCount = postInfo.stream().collect(Collectors.groupingBy(score -> score.get("section_name") + "-" + score.get("post_name"),
                Collectors.summingInt(score -> Integer.parseInt(score.get("police").toString()) + Integer.parseInt(score.get("auxiliary").toString()))));

        Map<String, Integer> postGroupByPostCount = postInfo.stream().collect(Collectors.groupingBy(score -> score.get("post_name").toString(), Collectors.summingInt(score -> 1)));
        Map<String, Integer> postGroupByPostCountAllPolice = postInfo.stream().collect(Collectors.groupingBy(score -> score.get("post_name").toString(),
                Collectors.summingInt(score -> Integer.parseInt(score.get("police").toString()) + Integer.parseInt(score.get("auxiliary").toString()))));


        String title = "交警勤务岗位统计表";
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        Font headfont = MyExcelUtil.createCellBaseFont(writer, "微软雅黑", (short) 24, IndexedColors.BLACK1.getIndex(), Font.U_NONE, true, false, false);
        CellStyle headCellStyle = MyExcelUtil.createCellBaseStyle(writer, headfont, false, IndexedColors.WHITE.getIndex(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
        writer.setSheet(0).renameSheet("交警勤务岗位统计表");
        writer.merge(0, 1, 0, 20, title, headCellStyle);

        MyExcelUtil.setCellStyleNoBorder(writer.createCellStyle(20, 0));
        MyExcelUtil.setCellStyleNoBorder(writer.createCellStyle(20, 1));
        MyExcelUtil.setCellStyleNoBorder(writer.createCellStyle(0, 2));

        Font font = MyExcelUtil.createCellBaseFont(writer, "微软雅黑", (short) 16, IndexedColors.GREY_80_PERCENT.getIndex(), Font.U_NONE, false, false, false);
        CellStyle cellStyle = MyExcelUtil.createCellBaseStyle(writer, font, true, IndexedColors.GREY_25_PERCENT.getIndex(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
        //设置标题行属性
        writer.setRowHeight(0, 40);
        writer.merge(2, 3, 1, 1, "总岗位", cellStyle);
        writer.writeCellValue(1, 4, "");

        writer.setColumnWidth(1, 9);
        writer.merge(2, 3, 2, 2, "每日部署警力", cellStyle);
        writer.writeCellValue(2, 4, "");
        writer.setColumnWidth(2, 18);
        writer.setStyle(cellStyle, 1, 4);
        writer.setStyle(cellStyle, 2, 4);

        Font fontRed = MyExcelUtil.createCellBaseFont(writer, "微软雅黑", (short) 16, IndexedColors.RED.getIndex(), Font.U_NONE, false, false, false);
        CellStyle cellStyleRed = MyExcelUtil.createCellBaseStyle(writer, fontRed, true, IndexedColors.WHITE.getIndex(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
        for (int i = 0; i < dutyPosts.size(); i++) {
            // 合并单元格写入岗位名
            writer.merge(2, 3, i * 2 + 3, i * 2 + 4, dutyPosts.get(i).getPostName(), cellStyle);
            // 循环写入下行文字
            writer.writeCellValue((i * 2) + 3, 4, "岗位");
            // 设置单元格样式
            writer.setStyle(cellStyleRed, (i * 2) + 3, 4);
            writer.writeCellValue((i * 2) + 4, 4, "每班次警力配置");
            writer.setStyle(cellStyleRed, (i * 2) + 4, 4);

            writer.setColumnWidth((i * 2) + 4, 21);
            // 设置单元格宽度
            writer.setColumnWidth((i * 2) + 3, 7);


        }

//        Font whitefont = MyExcelUtil.createCellBaseFont(writer, "微软雅黑", (short) 18, IndexedColors.WHITE.getIndex(), Font.U_NONE, true, false, false);
//        CellStyle flatPeakCellStyle = MyExcelUtil.createCellBaseStyle(writer, whitefont, true, IndexedColors.BRIGHT_GREEN.getIndex(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
//        CellStyle fastigiumCellStyle = MyExcelUtil.createCellBaseStyle(writer, whitefont, true, IndexedColors.ORANGE.getIndex(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
//        CellStyle nighttimePeakCellStyle = MyExcelUtil.createCellBaseStyle(writer, whitefont, true, IndexedColors.GREY_25_PERCENT.getIndex(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
//        writer.merge(0, 1, 22, 23, "平峰期", flatPeakCellStyle);
//        writer.merge(0, 1, 24, 25, "高峰期", fastigiumCellStyle);
//        writer.merge(0, 1, 26, 27, "夜间", nighttimePeakCellStyle);
//
//        writer.merge(2, 4, 22, 22, "岗位", cellStyleRed);
//        writer.merge(2, 4, 23, 23, "应签", cellStyleRed);
//        writer.merge(2, 4, 24, 24, "岗位", cellStyleRed);
//        writer.merge(2, 4, 25, 25, "应签", cellStyleRed);
//        writer.merge(2, 4, 26, 26, "岗位", cellStyleRed);
//        writer.merge(2, 4, 27, 27, "应签", cellStyleRed);

        CellStyle cellStyleBorderBlue = writer.createCellStyle();
        cellStyleBorderBlue.setBorderBottom(BorderStyle.THICK);
        cellStyleBorderBlue.setBottomBorderColor(IndexedColors.PALE_BLUE.getIndex());
        cellStyleBorderBlue.setAlignment(HorizontalAlignment.CENTER);
        cellStyleBorderBlue.setVerticalAlignment(VerticalAlignment.CENTER);
        List<CellStyle> cellStyles = backgroundColorStyleList(writer);
        for (int i = 0; i < sections.size(); i++) {
            // 第一列 部门名称
            writer.writeCellValue(0, i + 5, sections.get(i).getSectionName());
            writer.setStyle(cellStyleBorderBlue, 0, i + 5);
            writer.setColumnWidth(0, 24);
            writer.setRowHeight(i + 5, 18);
            // 总岗位
            writer.writeCellValue(1, i + 5, postGroupBySection.get(sections.get(i).getSectionName()).size());
            // 每日部署警力
            writer.writeCellValue(2, i + 5, postGroupBySectionCount.get(sections.get(i).getSectionName()));

            for (int j = 0; j < dutyPosts.size(); j++) {
                // 合并单元格写入岗位名
                try {
                    writer.writeCellValue(j * 2 + 3, i + 5, postGroupBySectionAndPost.get(sections.get(i).getSectionName() + "-" + dutyPosts.get(j).getPostName()).size());
                    writer.writeCellValue(j * 2 + 4, i + 5, postGroupBySectionAndPostCount.get(sections.get(i).getSectionName() + "-" + dutyPosts.get(j).getPostName()));
                } catch (Exception e) {
                    e.printStackTrace();
                    writer.writeCellValue(j * 2 + 3, i + 5, 0);
                    writer.writeCellValue(j * 2 + 4, i + 5, 0);
                }
                //设置单元格背景
                writer.setStyle(cellStyles.get(j), j * 2 + 3, i + 5);
                writer.setStyle(cellStyles.get(j), j * 2 + 4, i + 5);
            }
        }

        // 总计部署警力
        int postAllPoliceCount = postInfo.stream().mapToInt(score -> Integer.parseInt(score.get("police").toString()) + Integer.parseInt(score.get("auxiliary").toString())).sum();
        // 第一列 部门名称
        writer.writeCellValue(0, sections.size() + 5, "总计");
        writer.setStyle(cellStyleBorderBlue, 0, sections.size() + 5);
        writer.setColumnWidth(0, 24);
        writer.setRowHeight(sections.size() + 5, 18);
        // 总计岗位
        writer.writeCellValue(1, sections.size() + 5, postInfo.size());
        // 总计部署警力
        writer.writeCellValue(2, sections.size() + 5, postAllPoliceCount);

        for (int j = 0; j < dutyPosts.size(); j++) {
            // 合并单元格写入岗位名
            try {
                writer.writeCellValue(j * 2 + 3, sections.size() + 5, postGroupByPostCount.get(dutyPosts.get(j).getPostName()));
                writer.writeCellValue(j * 2 + 4, sections.size() + 5, postGroupByPostCountAllPolice.get(dutyPosts.get(j).getPostName()));
            } catch (Exception e) {
                e.printStackTrace();
                writer.writeCellValue(j * 2 + 3, sections.size() + 5, 0);
                writer.writeCellValue(j * 2 + 4, sections.size() + 5, 0);
            }
            //设置单元格背景
            writer.setStyle(cellStyles.get(j), j * 2 + 3, sections.size() + 5);
            writer.setStyle(cellStyles.get(j), j * 2 + 4, sections.size() + 5);
        }

        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=out.xls");
            ServletOutputStream out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (Exception e) {
            log.error("读取excel异常", e);
        }

    }

    public List<CellStyle> backgroundColorStyleList(ExcelWriter writer) {
        List<CellStyle> style = new ArrayList<>();
        List<Short> color = new ArrayList<>(Arrays.asList(IndexedColors.LIME.getIndex(), IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex(),
                IndexedColors.LEMON_CHIFFON.getIndex(), IndexedColors.GREY_25_PERCENT.getIndex(), IndexedColors.TAN.getIndex(),
                IndexedColors.LIGHT_TURQUOISE.getIndex(), IndexedColors.LIGHT_ORANGE.getIndex(), IndexedColors.TURQUOISE.getIndex(),
                IndexedColors.CORNFLOWER_BLUE.getIndex(), IndexedColors.CORNFLOWER_BLUE.getIndex()));
        Font whitefont = MyExcelUtil.createCellBaseFont(writer, "微软雅黑", (short) 11, IndexedColors.BLACK1.getIndex(), Font.U_NONE, false, false, false);
        for (int i = 0; i < 10; i++) {
            CellStyle flatPeakCellStyle = MyExcelUtil.createCellBaseStyle(writer, whitefont, true, color.get(i), HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
            style.add(flatPeakCellStyle);
        }
        return style;
    }

    /**
     * 按日统计导出
     */
    @Override
    public String StatisticsExport(HttpServletResponse response, Integer sectionId, String startTime, String
            endTime) throws IOException {
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        //获取需统计的各支队
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);

        List<SignGenerals> signGenerals = signGeneralMapper.findSignGeneral(sectionId, startTime);

        writer.addHeaderAlias("sectionName", "单位");
        writer.addHeaderAlias("signNum", "总签到人数");
        writer.addHeaderAlias("policeNum", "路面警力签到数");
        writer.addHeaderAlias("policeRate", "路面警力签到率");
        writer.addHeaderAlias("duration", "人均在线时长（分钟）");
        writer.addHeaderAlias("mileage", "人均巡逻里程（公里）");
        writer.addHeaderAlias("siteIllegal", "现场执法量");
        writer.addHeaderAlias("offsiteIllegal", "非现场执法量");
        writer.addHeaderAlias("jiechu", "接处警量");
        writer.addHeaderAlias("problem", "主动上报警情量");

        String times = "(" + DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + ")";
        String tal = "郑州交管局每日全项勤务数据统计表  " + times;

        // 合并单元格后的标题行，使用默认标题样式
        writer.merge(9, tal);

        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(signGenerals, true);

        writer.setRowHeight(0, 50);
        writer.setRowHeight(1, 35);
        writer.setColumnWidth(-1, 10);
        writer.renameSheet("郑州交管局每日全项勤务数据统计表");

        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        ServletOutputStream out = response.getOutputStream();
        // 关闭writer，释放内存
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

        return fileName;
    }


    @Override
    public String SignInExports(HttpServletResponse response, Integer sectionId, String startTime, String
            endTime, Integer shiftop) throws IOException, ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(simpleDateFormat.parse(startTime));
        String format1 = simpleDateFormat.format(simpleDateFormat.parse(endTime));
        int type = 1;
        if (format.equals(format1)) {
            type = 2;
        }

        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        Map<String, CellStyle> cells = getCells(writer);

        // 设置只导出有别名的字段
        writer.setOnlyAlias(true);
        boolean flag = true;
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        //包含的大队
        List<Map<String, Object>> mapList = signMapper.signInSpecialNumbers(sectionId, startTime, endTime, null, null);

        for (Map<String, Object> map : mapList) {

            //警员数据
            List<SignStatistics> signInAfews;
            if (type == 2) {
                signInAfews = signStatisticsMapper.findSignStatis(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime);
            } else {
                signInAfews = signStatisticsMapper.findSignStatisByWeek(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime);
            }


            writer.addHeaderAlias("sectionName", "单位");
            writer.addHeaderAlias("name", "姓名");
            writer.addHeaderAlias("warningSignal", "警号");
            writer.addHeaderAlias("duration", "在线时长");
            writer.addHeaderAlias("mileage", "巡逻里程");
            writer.addHeaderAlias("illegalNum", "执法量");
            writer.addHeaderAlias("jiechuNum", "接警量");
            writer.addHeaderAlias("problemNum", "上报警情数");
            writer.addHeaderAlias("signName", "签到岗位");
            writer.addHeaderAlias("equipages", "绑定装备");
            if (type == 2) {
                writer.addHeaderAlias("signNum", "签到次数");

            } else {
                writer.addHeaderAlias("signNum", "签到天数");

            }


            String sectionName = map.get("sectionName").toString();
            String name = sectionName.substring(0, sectionName.indexOf("队") + 1);
            String times;
            String tal;
            if (type == 2) {
                times = "日期：" + simpleDateFormat.format(simpleDateFormat.parse(startTime)) + " \n";
                tal = "\t\t\t\t" + name + "每日主要业务数据统计表" + "\t\t\t\t\t\t" + times + "\n";
            } else {
                times = "日期：" + simpleDateFormat.format(simpleDateFormat.parse(startTime)) + " ~ " + simpleDateFormat.format(simpleDateFormat.parse(endTime)) + " \n";
                tal = "\t\t\t\t" + name + "主要业务数据统计表" + "\t\t\t\t\t\t" + times + "\n";
            }

            if (flag) {
                if (type == 2) {
                    writer.renameSheet(DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + map.get("sectionName") + "勤务统计表");

                } else {
                    writer.renameSheet(DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + " ~ " + DateUtil.format(DateUtil.parseDate(endTime), "MM.dd") + map.get("sectionName") + "勤务统计表");

                }
                flag = false;
            } else {
                if (type == 2) {
                    writer.setSheet(DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + map.get("sectionName") + "勤务统计表");

                } else {
                    writer.setSheet(DateUtil.format(DateUtil.parseDate(startTime), "MM.dd") + " ~ " + DateUtil.format(DateUtil.parseDate(endTime), "MM.dd") + map.get("sectionName") + "勤务统计表");

                }
            }

            // 合并单元格后的标题行，使用默认标题样式

            writer.merge(11, tal);
            // 一次性写出内容，使用默认样式，强制输出标题
            writer.write(signInAfews, true);


            for (int i = 0; i < signInAfews.size(); i++) {
                double mileage = signInAfews.get(i).getMileage();
                String duration = signInAfews.get(i).getDuration();
                Integer integer = Integer.valueOf(duration.substring(duration.indexOf("时") + 1, duration.indexOf("分")));
                Integer num = Integer.valueOf(duration.substring(0, duration.indexOf("小")));
                int time = integer + num;
                List<Integer> dataId = sectionMapper.findSectionByPid(Integer.valueOf(map.get("sectionpid").toString()));
                if (dataId.indexOf(signInAfews.get(i).getSectionId()) == -1 && (mileage < 0.1 || time < 1)) {

                    //指定单元格样式
                    for (int j = 0; j < 10; j++) {
                        CellStyle style = cells.get("cell");
                        writer.setStyle(style, j, 2 + i);

                        //指定单元格样式
                        /*CellStyle cellStyle = writer.getCellStyle();
                        cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
                        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                        cellStyle.setAlignment(HorizontalAlignment.CENTER);
                        // 顶边栏
                        cellStyle.setBorderTop(BorderStyle.THIN);
                        // 右边栏
                        cellStyle.setBorderRight(BorderStyle.THIN);
                        // 底边栏
                        cellStyle.setBorderBottom(BorderStyle.THIN);
                        // 左边栏
                        cellStyle.setBorderLeft(BorderStyle.THIN);*/


                    }

                }

            }

            writer.setRowHeight(0, 40);
            writer.setRowHeight(1, 20);
            writer.setColumnWidth(-1, 10);
            writer.setColumnWidth(0, 20);
            writer.setColumnWidth(3, 20);
            writer.setColumnWidth(8, 20);
        }
        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        ServletOutputStream out = response.getOutputStream();
        // 关闭writer，释放内存
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
        return fileName;

    }

    private Map<String, CellStyle> getCells(ExcelWriter writer) {
        CellStyle cellStyle = writer.createCellStyle(1, 1);
        cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        // 顶边栏
        cellStyle.setBorderTop(BorderStyle.THIN);
        // 右边栏
        cellStyle.setBorderRight(BorderStyle.THIN);
        // 底边栏
        cellStyle.setBorderBottom(BorderStyle.THIN);
        // 左边栏
        cellStyle.setBorderLeft(BorderStyle.THIN);
        Map<String, CellStyle> map = new HashMap<>();
        map.put("cell", cellStyle);
        return map;
    }


    /**
     * 统计昨天人员的数据
     */
    @Override
    public void Statistics(String startDay, String endDay) {
        if (StringUtils.isEmpty(startDay) || StringUtils.isEmpty(endDay)) {
            startDay = DataTime.getStartDay();
            endDay = DataTime.getEndDay();
        }
        List<Map<String, Object>> staffs = staffMapper.findStaffs();
        for (Map<String, Object> staff : staffs) {
            SignStatistics signStatistics = new SignStatistics();
            signStatistics.setSectionId(Integer.valueOf(staff.get("sys_section_id").toString()));
            signStatistics.setSectionPid(Integer.valueOf(staff.get("section_pid").toString()));
            signStatistics.setSectionName(staff.get("section_name").toString());
            signStatistics.setName(staff.get("staff_name").toString());
            signStatistics.setStaffId(Integer.valueOf(staff.get("sys_staff_id").toString()));
            signStatistics.setWarningSignal(staff.get("staff_num").toString());
            Map map1 = duration(Integer.valueOf(staff.get("sys_staff_id").toString()), startDay, endDay);

            signStatistics.setDuration(map1.get("duration").toString());
            signStatistics.setMileage(Double.valueOf(map1.get("mileages").toString()));
            signStatistics.setIllegalNum(illegalDataMapper.selectCount(Wrappers.<IllegalData>lambdaQuery()
                    .eq(IllegalData::getWarningSignal, staff.get("staff_num"))
                    .between(IllegalData::getWfsj, startDay, endDay)));
            signStatistics.setProblemNum(problemMapper.selectCount(Wrappers.<Problem>lambdaQuery()
                    .eq(Problem::getSysStaffId, staff.get("sys_staff_id"))
                    .between(Problem::getProblemDate, startDay, endDay)));
            signStatistics.setJiechuNum(policeDataMapper.selectCount(Wrappers.<PoliceData>lambdaQuery()
                    .eq(PoliceData::getWarningsignal, staff.get("staff_num"))
                    .between(PoliceData::getJjsj01, startDay, endDay)));
            List<Sign> staffData = signMapper.selectList(Wrappers.<Sign>lambdaQuery()
                    .eq(Sign::getWarningsignal, staff.get("staff_num"))
                    .between(Sign::getSignintime, startDay, endDay));
            if (staffData.size() > 0) {
                StringBuilder stringBuffer = new StringBuilder();
                for (Sign staffDatum : staffData) {
                    stringBuffer.append(staffDatum.getAssignmentname());
                    stringBuffer.append(",");
                }
                stringBuffer.delete(stringBuffer.length() - 1, stringBuffer.length());
                signStatistics.setSignName(stringBuffer.toString());
            }
            signStatistics.setSignNum(staffData.size());
            signStatistics.setSignTime(DateUtil.parseDateTime(startDay));
            List<Map<String, Objects>> equipageList = signEquipageService.getEquipageBy(staff.get("staff_num").toString());
            StringBuilder equipages = new StringBuilder();
            for (Map<String, Objects> map : equipageList) {
                equipages.append(map.get("type")).append(",");
            }
            if(equipages.length() > 0) {
                equipages.delete(equipages.length() - 1, equipages.length());
            }
            signStatistics.setEquipages(equipages.toString());

            signStatistics.setCreatTime(new Date());

            signStatisticsMapper.insertIgnoreNull(signStatistics);
        }

    }

    @Override
    public String SignInExportLochus(HttpServletResponse response, Integer sectionDId, Integer sectionId, String
            startTime, String
                                             endTime, String station) throws IOException, ParseException {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Integer comment = null;
        if (StringUtils.isNotEmpty(station)) {
            if ("特勤".equals(station)) {
                comment = 2;
            } else {
                comment = 1;
            }
        }
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 设置只导出有别名的字段
        writer.setOnlyAlias(true);
        boolean flag = true;
        //包含的中队
        List<Map<String, Object>> mapList = signMapper.signInSpecialNumberLochus(sectionDId, sectionId, startTime, endTime, null, comment);
        for (Map<String, Object> map : mapList) {
            ArrayList<Map<String, Object>> rows = CollUtil.newArrayList();
            //人员
            List<Map> signInAfews = signMapper.SignInStationLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, null);
            for (Map signInAfew : signInAfews) {
                Map<String, Object> rowe1 = new LinkedHashMap<>();
                rowe1.put("单位", signInAfew.get("sectionname"));
                rowe1.put("姓名", signInAfew.get("staffname"));
                rowe1.put("警号", signInAfew.get("warningsignal"));
                //巡查时长和里程
                Map map1 = duration(Integer.valueOf(signInAfew.get("staffid").toString()), startTime, endTime);
                rowe1.put("在线时长", map1.get("duration"));
                rowe1.put("巡逻里程", map1.get("mileages"));


                //加入该警员的签到岗位
               /* merges(signInAfews);
                List<Map> detail = (List<Map>) signInAfew.get("detail");
                StringBuilder sb = new StringBuilder();
                for (Map map2 : detail) {
                    sb.append(map2.get("station"));
                    sb.append(",");
                }
                sb.delete(sb.length() - 1, sb.length());*/
                rowe1.put("签到岗位", signInAfew.get("assignmentname"));

                if ("2".equals(signInAfew.get("comment"))) {
                    rowe1.put("班次", "特勤");
                } else {
                    if ("1".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "上午班");
                    }
                    if ("2".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "下午班");
                    }
                    if ("3".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "夜巡");
                    }
                    if ("4".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "全天班");
                    }

                }
                rows.add(rowe1);
            }

            String times = "日期：" + simpleDateFormat.format(simpleDateFormat.parse(startTime)) + " \n";
            String signNums = "签到数：" + signInAfews.size();
            if (flag) {
                writer.renameSheet(map.get("sectionName") + "签到统计1");
                flag = false;
            } else {
                writer.setSheet(map.get("sectionName") + "签到统计");
            }
            String sectionName = map.get("sectionName").toString();
            String name = sectionName.substring(sectionName.indexOf("队") + 1);
            // 合并单元格后的标题行，使用默认标题样式
            writer.merge(6, name + "  " + times + signNums);
            // 一次性写出内容，使用默认样式，强制输出标题
            writer.write(rows, true);
            writer.setRowHeight(0, 45);
            writer.setColumnWidth(-1, 20);
            writer.setColumnWidth(5, 30);

        }

        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        ServletOutputStream out = response.getOutputStream();


        // 关闭writer，释放内存
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

        return fileName;
    }

    /*@Override
    public String SignInExportLochus(HttpServletResponse response, Integer sectionDId, Integer sectionId, String startTime, String
            endTime, String station) throws IOException, ParseException {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Integer comment = null;
        if (StringUtils.isNotEmpty(station)) {
            if ("特勤".equals(station)) {
                comment = 2;
            } else {
                comment = 1;
            }
        }
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 设置只导出有别名的字段
        writer.setOnlyAlias(true);
        boolean flag = true;
        //包含的中队
        List<Map<String, Object>> mapList = signMapper.signInSpecialNumberLochus(sectionDId, sectionId, startTime, endTime, null, comment);
        for (Map<String, Object> map : mapList) {
            ArrayList<Map<String, Object>> rows = CollUtil.newArrayList();
            //人员
            List<Map> signInAfews = signMapper.SignInStationLochus(Integer.valueOf(map.get("sectionpid").toString()), startTime, endTime, null, null);
            for (Map signInAfew : signInAfews) {
                Map<String, Object> rowe1 = new LinkedHashMap<>();
                rowe1.put("单位", signInAfew.get("sectionname"));
                rowe1.put("姓名", signInAfew.get("staffname"));
                rowe1.put("警号", signInAfew.get("warningsignal"));
                //巡查时长和里程
                Map map1 = duration(Integer.valueOf(signInAfew.get("staffid").toString()), startTime, endTime);
                rowe1.put("在线时长", map1.get("duration"));
                rowe1.put("巡逻里程", map1.get("mileages"));


                //加入该警员的签到岗位
                merges(signInAfews);
                List<Map> detail = (List<Map>) signInAfew.get("detail");
                StringBuilder sb = new StringBuilder();
                for (Map map2 : detail) {
                    sb.append(map2.get("station"));
                    sb.append(",");
                }
                sb.delete(sb.length() - 1, sb.length());
                rowe1.put("签到岗位", sb.toString());
                if ("2".equals(signInAfew.get("comment"))) {
                    rowe1.put("班次", "特勤");
                } else {
                    if ("1".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "上午班");
                    }
                    if ("2".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "下午班");
                    }
                    if ("3".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "夜巡");
                    }
                    if ("4".equals(signInAfew.get("shiftop"))) {
                        rowe1.put("班次", "全天班");
                    }

                }
                rows.add(rowe1);
            }

            String times = "日期：" + simpleDateFormat.format(simpleDateFormat.parse(startTime)) + " \n";
            String signNums = "签到数：" + signInAfews.size();
            if (flag) {
                writer.renameSheet(map.get("sectionName") + "签到统计1");
                flag = false;
            } else {
                writer.setSheet(map.get("sectionName") + "签到统计");
            }
            String sectionName = map.get("sectionName").toString();
            String name = sectionName.substring(sectionName.indexOf("队") + 1);
            // 合并单元格后的标题行，使用默认标题样式
            writer.merge(6, name + "  " + times + signNums);
            // 一次性写出内容，使用默认样式，强制输出标题
            writer.write(rows, true);
            writer.setRowHeight(0, 45);
            writer.setColumnWidth(-1, 20);
            writer.setColumnWidth(5, 30);

        }

        String fileName = System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        ServletOutputStream out = response.getOutputStream();


        // 关闭writer，释放内存
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

        return fileName;
    }*/


    @Override
    public Map signInNum(Integer sectionId, String time, HttpServletRequest request) {
        Map<String, String> time1 = getTime(time);
        //在线数
        //List<Map> maps = signMapper.OnLineInNum(sectionId);
        sectionId = getSectionId(request);
        //当天累计签到
//        String startTime1 = DateUtil.today() + " 00:00:00";
//        String endTime1 = DateUtil.today() + " 23:59:59";
//        String yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday()).toString();
//        String yesterdayEnd = DateUtil.endOfDay(DateUtil.yesterday()).toString();
//        StatisticsVo todayPolice = signMapper.todayPolice(startTime1, endTime1, sectionId);
//        int yesterdayPolice = signMapper.yesterdayPolice(yesterdayStart, yesterdayEnd, sectionId);
//
//        String startTime = DateUtil.today() + " 00:00:00";
//        String endTime = DateUtil.today() + " 23:59:59";
//        StatisticsVo statisticsVos = signMapper.specialTodayPoliceBySecion(startTime, endTime, sectionId);
        //当天累计签到
        int totalPoliceNum = signMapper.policeSignCount(sectionId, null);
        //巡查里程
        double i = gpsMapper.totalDistance(sectionId, time1.get("startTime"), time1.get("endTime"));
        Map<String, Object> map = new HashMap<>();
//        map.put("SignIn", todayPolice.getTotalNum() + yesterdayPolice + statisticsVos.getTotalNum());
        map.put("SignIn", totalPoliceNum);
        map.put("distance", i);
        return map;
    }

    @Override
    public List<Map<String, Object>> signInNumBySection(Integer sectionId, String time, Integer depthNumber) {
        depthNumber++;
        //Map<String, String> time1 = getTime(time);
        //签到包括的大队
        if (sectionId != null) {
            Section section = sectionMapper.selectByPrimaryKey(sectionId);
            if (section.getSectionPid() == 74 && !section.getSectionName().contains("支队")) {
                sectionId = null;
            }
        }

        List<Map<String, Object>> mapList = sectionMapper.findSectionByXarea(sectionId);
        for (Map map : mapList) {
            //民警签到人数
            List<Map> mapList1 = signMapper.SignInNums(Integer.valueOf(map.get("sectionPid").toString()), time);
            map.put("signInNum", mapList1.size());
            //辅警签到人数
            List<Map> mapList2 = signMapper.auxiliarySignInNum(Integer.valueOf(map.get("sectionPid").toString()), time);
            map.put("auxiliary", mapList2.size());
            map.put("date", time);

        }
        Integer signInNum = mapList.stream().map(map -> (Integer) map.get("signInNum")).reduce(0, Integer::sum);
        if (signInNum < 10 && depthNumber <= maxDepth) {
            String string = DateUtil.offsetDay(DateUtil.parseDate(time), -1).toString("yyyy-MM-dd");
            return signInNumBySection(sectionId, string, depthNumber);
        }
        return mapList;
    }

    @Override
    public List<Map<String, Object>> signInNumByLochus(Integer sectionId, String time, Integer depthNumber) {
        depthNumber++;
        Map<String, String> time1 = getTime(time);
        if (sectionId != null) {
            Section section = sectionMapper.selectByPrimaryKey(sectionId);
            if (section.getSectionPid() == 74 && !section.getSectionName().contains("支队")) {
                return this.signInNumBySection(null, time, 0);
            }

        }
        //签到包括的中队
        List<Map<String, Object>> mapList = signMapper.SignInLochus(sectionId, time);
        Map<String, Object> maps = new HashMap<>();
        maps.put("sectionid", sectionId);
        maps.put("sectionName", "支队");
        mapList.add(maps);
        for (Map map : mapList) {
            map.put("date", time);
            List<Map> mapList1 = signMapper.SignInNumLochus(Integer.valueOf(map.get("sectionid").toString()), time1.get("startTime"), time1.get("endTime"));
            map.put("signInNum", mapList1.size());
            List<Map> mapList2 = signMapper.auxiliarySignInNumLochus(Integer.valueOf(map.get("sectionid").toString()), time);
            map.put("auxiliary", mapList2.size());
            if (map.get("sectionName").toString().contains("机关")) {
                int signInNum = Integer.valueOf(map.get("signInNum").toString());
                int auxiliary = Integer.valueOf(map.get("auxiliary").toString());
                map.put("signInNum", signInNum + signMapper.SignInByLochus(sectionId, "民警").size());
                map.put("auxiliary", auxiliary + signMapper.SignInByLochus(sectionId, "辅警").size());
            }
        }
        Integer signInNum = mapList.stream().map(map -> (Integer) map.get("signInNum")).reduce(0, Integer::sum);
        if (signInNum < 10 && depthNumber <= maxDepth) {
            String string = DateUtil.offsetDay(DateUtil.parseDate(time), -1).toString("yyyy-MM-dd");
            return signInNumByLochus(sectionId, string, depthNumber);
        }

        /*mapList.sort(new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                //这里因为我的mapKey对应的值有小数，我去掉了小数部分
                Integer value1 = Double.valueOf(o1.get("sectionid").toString()).intValue();
                Integer value2 = Double.valueOf(o2.get("sectionid").toString()).intValue();
                //此时为升序，
                return value1.compareTo(value2);
                //为降序
                //return value2.compareTo(value1);
            }
        });*/


        return mapList;
    }


    @Override
    public List<Map<String, Object>> distanceRanking(Integer sectionId, String time, Integer depthNumber) {
        depthNumber++;
        Map<String, String> time1 = getTime(time);
        //签到包括的大队
        List<Map<String, Object>> mapList = gpsMapper.totalDistanceByTime(sectionId, time1.get("startTime"), time1.get("endTime"));
        for (Map<String, Object> map : mapList) {
            map.put("date", time);
        }
        Double distance = mapList.stream().map(map -> (Double) map.get("distance")).reduce(0d, Double::sum);
        if (distance < 100 && depthNumber <= maxDepth) {
            String string = DateUtil.offsetDay(DateUtil.parseDate(time), -1).toString("yyyy-MM-dd");
            return distanceRanking(sectionId, string, depthNumber);
        }
        return mapList;
    }


    @Override
    public List<Map<String, Object>> distanceRankingLochus(Integer sectionId, String time, Integer depthNumber) {
        depthNumber++;
        Map<String, String> time1 = getTime(time);
        List<Map<String, Object>> mapList = gpsMapper.totalLochusByTime(sectionId, time1.get("startTime"), time1.get("endTime"));
        for (Map<String, Object> map : mapList) {
            map.put("date", time);
        }
        Double distance = mapList.stream().map(map -> (Double) map.get("distance")).reduce(0d, Double::sum);
        if (distance < 100 && depthNumber <= maxDepth) {
            String string = DateUtil.offsetDay(DateUtil.parseDate(time), -1).toString("yyyy-MM-dd");
            return distanceRankingLochus(sectionId, string, depthNumber);
        }
        return mapList;
    }


    private static String[] week = new String[]{"周一", "周二", "周三", "周四", "周五", "周六", "周日"};

    //大队签到数和在线数折线图展示 统计这周的在线数和上周的签到数
    @Override
    public List<Map> SignInComparison(Integer sectionId) throws ParseException {
        //本周签到
        int[] lastWeek = new int[7];
        int[] thisWeek = new int[7];
        //上周开始时间和结束时间
        String beginDayOfLastWeek = com.zygh.lz.util.DateUtil.getBeginDayOfLastWeek();
        String endDayOfLastWeek = com.zygh.lz.util.DateUtil.getEndDayOfLastWeek();
        List startEnd = com.zygh.lz.util.DateUtil.getStartEnd(beginDayOfLastWeek, endDayOfLastWeek);
        for (int i = 0; i < startEnd.size(); i++) {
            Map<String, String> time = getTime(startEnd.get(i).toString());
            //上周签到数 （按班车统计）
            List<Map> mapList = signMapper.SignInNum(sectionId, time.get("startTime"), time.get("endTime"));
            lastWeek[i] = mapList.size();
        }

        //本周开始时间和结束时间
        String timesWeekmorning = com.zygh.lz.util.DateUtil.getTimesWeekmorning();
        String timesWeeknight = com.zygh.lz.util.DateUtil.getTimesWeeknight();
        List weeklist = com.zygh.lz.util.DateUtil.getStartEnd(timesWeekmorning, timesWeeknight);
        for (int i = 0; i < weeklist.size(); i++) {
            Map<String, String> time = getTime(weeklist.get(i).toString());
            //本周在线数 （按人次统计）
            //List<Map> mapList = signMapper.OnLineInNum(sectionId, time.get("startTime"), time.get("endTime"), null);
            //本周签到数 （按班车统计）
            List<Map> mapList = signMapper.SignInNum(sectionId, time.get("startTime"), time.get("endTime"));
            thisWeek[i] = mapList.size();
        }
        List<Map> list = new ArrayList<>();
        Map map = new HashMap();
        map.put("week", week);
        map.put("lastWeek", lastWeek);
        map.put("thisWeek", thisWeek);
        list.add(map);
        return list;
    }

    //中队签到数和在线数折线图展示 统计这周的在线数和上周的签到数
    @Override
    public List<Map> SignInComparisonLochus(Integer sectionId) throws ParseException {
        //本周签到
        int[] lastWeek = new int[7];
        int[] thisWeek = new int[7];
        //上周开始时间和结束时间
        String beginDayOfLastWeek = com.zygh.lz.util.DateUtil.getBeginDayOfLastWeek();
        String endDayOfLastWeek = com.zygh.lz.util.DateUtil.getEndDayOfLastWeek();
        List startEnd = com.zygh.lz.util.DateUtil.getStartEnd(beginDayOfLastWeek, endDayOfLastWeek);
        for (int i = 0; i < startEnd.size(); i++) {
            Map<String, String> time = getTime(startEnd.get(i).toString());
            //上周签到数 （按班车统计）
            List<Map> mapList = signMapper.SignInNumLochus(sectionId, time.get("startTime"), time.get("endTime"));
            lastWeek[i] = mapList.size();
        }

        //本周开始时间和结束时间
        String timesWeekmorning = com.zygh.lz.util.DateUtil.getTimesWeekmorning();
        String timesWeeknight = com.zygh.lz.util.DateUtil.getTimesWeeknight();
        List weeklist = com.zygh.lz.util.DateUtil.getStartEnd(timesWeekmorning, timesWeeknight);
        for (int i = 0; i < weeklist.size(); i++) {
            Map<String, String> time = getTime(weeklist.get(i).toString());
            //本周在线数 （按人次统计）
            //List<Map> mapList = signMapper.OnLineInNumLochus(sectionId, time.get("startTime"), time.get("endTime"), null);
            //上周签到数 （按班车统计）
            List<Map> mapList = signMapper.SignInNumLochus(sectionId, time.get("startTime"), time.get("endTime"));
            thisWeek[i] = mapList.size();
        }
        List<Map> list = new ArrayList<>();
        Map map = new HashMap();
        map.put("week", week);
        map.put("lastWeek", lastWeek);
        map.put("thisWeek", thisWeek);
        list.add(map);
        return list;
    }

    @Override
    public List<Map> mileageBrokenLine(Integer sectionId) throws ParseException {
        //本周签到
        double[] lastWeek = new double[7];
        double[] thisWeek = new double[7];
        //上周开始时间和结束时间
        String beginDayOfLastWeek = com.zygh.lz.util.DateUtil.getBeginDayOfLastWeek();
        String endDayOfLastWeek = com.zygh.lz.util.DateUtil.getEndDayOfLastWeek();
        List startEnd = com.zygh.lz.util.DateUtil.getStartEnd(beginDayOfLastWeek, endDayOfLastWeek);
        for (int i = 0; i < startEnd.size(); i++) {
            Map<String, String> time = getTime(startEnd.get(i).toString());
            //上周里程数
            double distance = gpsMapper.totalDistance(sectionId, time.get("startTime"), time.get("endTime"));
            lastWeek[i] = distance;
        }

        //本周开始时间和结束时间
        String timesWeekmorning = com.zygh.lz.util.DateUtil.getTimesWeekmorning();
        String timesWeeknight = com.zygh.lz.util.DateUtil.getTimesWeeknight();
        List weeklist = com.zygh.lz.util.DateUtil.getStartEnd(timesWeekmorning, timesWeeknight);
        for (int i = 0; i < weeklist.size(); i++) {
            Map<String, String> time = getTime(weeklist.get(i).toString());
            //上周里程数
            double distances = gpsMapper.totalDistance(sectionId, time.get("startTime"), time.get("endTime"));
            thisWeek[i] = distances;
        }
        List<Map> list = new ArrayList<>();
        Map map = new HashMap();
        map.put("week", week);
        map.put("lastWeek", lastWeek);
        map.put("thisWeek", thisWeek);
        list.add(map);
        return list;
    }

    @Override
    public List<Map> mileageBrokenLineLochus(Integer sectionId) throws ParseException {
        //本周签到
        double[] lastWeek = new double[7];
        double[] thisWeek = new double[7];
        //上周开始时间和结束时间
        String beginDayOfLastWeek = com.zygh.lz.util.DateUtil.getBeginDayOfLastWeek();
        String endDayOfLastWeek = com.zygh.lz.util.DateUtil.getEndDayOfLastWeek();
        List startEnd = com.zygh.lz.util.DateUtil.getStartEnd(beginDayOfLastWeek, endDayOfLastWeek);
        for (int i = 0; i < startEnd.size(); i++) {
            Map<String, String> time = getTime(startEnd.get(i).toString());
            //上周里程数
            double distance = gpsMapper.totalDistanceLochus(sectionId, time.get("startTime"), time.get("endTime"));
            lastWeek[i] = distance;
        }

        //本周开始时间和结束时间
        String timesWeekmorning = com.zygh.lz.util.DateUtil.getTimesWeekmorning();
        String timesWeeknight = com.zygh.lz.util.DateUtil.getTimesWeeknight();
        List weeklist = com.zygh.lz.util.DateUtil.getStartEnd(timesWeekmorning, timesWeeknight);
        for (int i = 0; i < weeklist.size(); i++) {
            Map<String, String> time = getTime(weeklist.get(i).toString());
            //本周里程数
            double distances = gpsMapper.totalDistanceLochus(sectionId, time.get("startTime"), time.get("endTime"));
            thisWeek[i] = distances;
        }
        List<Map> list = new ArrayList<>();
        Map map = new HashMap();
        map.put("week", week);
        map.put("lastWeek", lastWeek);
        map.put("thisWeek", thisWeek);
        list.add(map);
        return list;
    }


    @Override
    public List<Map<String, Object>> findMileageBySection(Integer sectionId, String time, String staffname) {
        Map<String, String> time2 = getTime(time);

        return gpsMapper.distanceBySectionId(sectionId, time2.get("startTime"), time2.get("endTime"));
    }


    @Override
    public List<Map<String, Object>> findMileageByLochus(Integer sectionId, String time, String staffname) {
        Map<String, String> time2 = getTime(time);
        return gpsMapper.distanceBySectionId(sectionId, time2.get("startTime"), time2.get("endTime"));

    }

    @Override
    public List<Map> findTrackByStaffId(Integer staffId, String time) {
        //巡查记录
        List<Map> patrolrecordInfoById = patrolrecordMapper.findPatrolrecordInfoById(staffId, time);
        for (Map map : patrolrecordInfoById) {
            String signnum = map.get("signnum").toString();
            List<Map> signByNum = signMapper.findSignByNum(signnum);
            map.put("signinfo", signByNum);
            List<Gps> gpsList = gpsMapper.selectGpsByRecord(staffId, Integer.valueOf(map.get("sysPatrolRecordId").toString()));
            String allGps = gpsList.stream().map(x -> x.getCoordinate()).collect(Collectors.joining(","));
            map.put("distance", allGps);
        }
        return patrolrecordInfoById;
    }


    public static Map<String, String> getTime(String time) {
        Map<String, String> map = new HashMap<>();
        String startTime = null;
        String endTime = null;
        if (StringUtils.isNotEmpty(time)) {
            startTime = time + " 00:00:00";
            endTime = time + " 23:59:59";
        } else {
            map.put("startTime", startTime);
            map.put("endTime", endTime);
            return map;
        }

        map.put("startTime", startTime);
        map.put("endTime", endTime);
        return map;
    }

    @Override
    public List<Map> onlineNumber(Integer id) {
        List<Map> onlineSection = signMapper.findOnlineSection(id);
        for (Map map : onlineSection) {
            List<Map> mj = signMapper.findStaffByState("民警", Integer.parseInt(map.get("section_pid").toString()));
            List<Map> fj = signMapper.findStaffByState("辅警", Integer.parseInt(map.get("section_pid").toString()));
            map.put("mj", mj.size());
            map.put("fj", fj.size());
        }
        return onlineSection;
    }

    @Override
    public List<Map> totalMileage(Integer id) {
        //有部署岗位的大队
        List<Map> deploySection = xareaMapper.findDeploySection(id);
        for (Map map : deploySection) {
            Xareas xareas = new Xareas();
            xareas.setSectionDid(Integer.valueOf(map.get("section_Did").toString()))
                    .setStaffType("民警");
            int policeStrength = xareaMapper.findPoliceStrength(xareas);
            map.put("mj", policeStrength);
            xareas.setStaffType("辅警");
            int policeStrength1 = xareaMapper.findPoliceStrength(xareas);
            map.put("fj", policeStrength1);
            //大队总里程
            double mileage = gpsMapper.totalDistance(Integer.valueOf(map.get("section_Did").toString()), DateUtil.beginOfDay(new Date()).toString(), DateUtil.endOfDay(new Date()).toString());
            map.put("mileage", mileage);
        }
        return deploySection;
    }


}

